diff --git a/src/io/FileOutputStream.cxx b/src/io/FileOutputStream.cxx index c9e56c144..d6df7985b 100644 --- a/src/io/FileOutputStream.cxx +++ b/src/io/FileOutputStream.cxx @@ -4,13 +4,13 @@ #include "FileOutputStream.hxx" #include "lib/fmt/PathFormatter.hxx" #include "lib/fmt/SystemError.hxx" -#include "lib/fmt/ToBuffer.hxx" #ifdef _WIN32 #include #endif #ifdef __linux__ +#include "io/linux/ProcPath.hxx" #include #endif @@ -281,8 +281,7 @@ try { unlinkat(directory_fd.Get(), GetPath().c_str(), 0); /* hard-link the temporary file to the final path */ - if (linkat(-1, - FmtBuffer<64>("/proc/self/fd/{}", fd.Get()), + if (linkat(-1, ProcFdPath(fd), directory_fd.Get(), path.c_str(), AT_SYMLINK_FOLLOW) < 0) throw FmtErrno("Failed to commit {}", path); diff --git a/src/io/linux/ProcPath.hxx b/src/io/linux/ProcPath.hxx new file mode 100644 index 000000000..8a780defe --- /dev/null +++ b/src/io/linux/ProcPath.hxx @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: BSD-2-Clause +// Copyright CM4all GmbH +// author: Max Kellermann + +#pragma once + +#include "lib/fmt/ToBuffer.hxx" +#include "io/FileDescriptor.hxx" +#include "util/StringBuffer.hxx" + +/** + * Build the path to the "/proc/self/fd/" magic link of the given file + * descriptor. + */ +[[gnu::const]] +inline StringBuffer<32> +ProcFdPath(FileDescriptor fd) noexcept +{ + return FmtBuffer<32>("/proc/self/fd/{}", fd.Get()); +} + +/** + * Build the path to the "/proc/self/fdinfo/" file of the given file + * descriptor. + */ +[[gnu::const]] +inline StringBuffer<32> +ProcFdinfoPath(FileDescriptor fd) noexcept +{ + return FmtBuffer<32>("/proc/self/fdinfo/{}", fd.Get()); +}