Return AutoCloseFD in open-like functions
This reflects the fact that it is returning a new, "owned" file descriptor, that it is the caller's responsibility to close. Co-authored-by: Amaan Qureshi <git@amaanq.com>
This commit is contained in:
committed by
Amaan Qureshi
parent
02bb3d032d
commit
89dd96efbf
@@ -137,7 +137,7 @@ public:
|
||||
: state(state)
|
||||
, sampleInterval(period)
|
||||
, profileFd([&]() {
|
||||
AutoCloseFD fd = openNewFileForWrite(
|
||||
auto fd = openNewFileForWrite(
|
||||
profileFile,
|
||||
0660,
|
||||
{
|
||||
|
||||
@@ -554,7 +554,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results)
|
||||
by another process. We need to be sure that we can acquire an
|
||||
exclusive lock before deleting them. */
|
||||
if (baseName.find("tmp-", 0) == 0) {
|
||||
AutoCloseFD tmpDirFd = openDirectory(realPath);
|
||||
auto tmpDirFd = openDirectory(realPath);
|
||||
if (!tmpDirFd || !lockFile(tmpDirFd.get(), ltWrite, false)) {
|
||||
debug("skipping locked tempdir %s", PathFmt(realPath));
|
||||
return;
|
||||
|
||||
@@ -45,7 +45,7 @@ TEST(readLinkAt, works)
|
||||
sink.createDirectory(CanonPath("dir"));
|
||||
}
|
||||
|
||||
AutoCloseFD dirFd = openDirectory(tmpDir);
|
||||
auto dirFd = openDirectory(tmpDir);
|
||||
|
||||
EXPECT_EQ(readLinkAt(dirFd.get(), CanonPath("link")), OS_STR("target"));
|
||||
EXPECT_EQ(readLinkAt(dirFd.get(), CanonPath("relative")), OS_STR("../relative/path"));
|
||||
@@ -54,7 +54,7 @@ TEST(readLinkAt, works)
|
||||
EXPECT_EQ(readLinkAt(dirFd.get(), CanonPath("long")), string_to_os_string(longTarget));
|
||||
EXPECT_EQ(readLinkAt(dirFd.get(), CanonPath("a/b/link")), OS_STR("nested_target"));
|
||||
|
||||
AutoCloseFD subDirFd = openDirectory(tmpDir / "a");
|
||||
auto subDirFd = openDirectory(tmpDir / "a");
|
||||
EXPECT_EQ(readLinkAt(subDirFd.get(), CanonPath("b/link")), OS_STR("nested_target"));
|
||||
|
||||
// Test error cases - expect SystemError on both platforms
|
||||
@@ -107,7 +107,7 @@ TEST(openFileEnsureBeneathNoSymlinks, works)
|
||||
SymlinkNotAllowed);
|
||||
}
|
||||
|
||||
AutoCloseFD dirFd = openDirectory(tmpDir);
|
||||
auto dirFd = openDirectory(tmpDir);
|
||||
|
||||
// Helper to open files with platform-specific arguments
|
||||
auto openRead = [&](std::string_view path) -> AutoCloseFD {
|
||||
|
||||
@@ -39,7 +39,7 @@ TEST(fchmodatTryNoFollow, works)
|
||||
ASSERT_NO_THROW(chmod(tmpDir / "file", 0644));
|
||||
ASSERT_NO_THROW(chmod(tmpDir / "dir", 0755));
|
||||
|
||||
AutoCloseFD dirFd = openDirectory(tmpDir);
|
||||
auto dirFd = openDirectory(tmpDir);
|
||||
ASSERT_TRUE(dirFd);
|
||||
|
||||
struct ::stat st;
|
||||
@@ -104,7 +104,7 @@ TEST(fchmodatTryNoFollow, fallbackWithoutProc)
|
||||
if (mount("tmpfs", "/proc", "tmpfs", 0, 0) == -1)
|
||||
_exit(1);
|
||||
|
||||
AutoCloseFD dirFd = openDirectory(tmpDir);
|
||||
auto dirFd = openDirectory(tmpDir);
|
||||
if (!dirFd)
|
||||
exit(1);
|
||||
|
||||
|
||||
@@ -263,7 +263,7 @@ std::filesystem::path readLink(const std::filesystem::path & path)
|
||||
|
||||
std::string readFile(const std::filesystem::path & path)
|
||||
{
|
||||
AutoCloseFD fd = openFileReadonly(path);
|
||||
auto fd = openFileReadonly(path);
|
||||
if (!fd)
|
||||
throw NativeSysError("opening file %1%", PathFmt(path));
|
||||
return readFile(fd.get());
|
||||
@@ -286,7 +286,7 @@ void readFile(const std::filesystem::path & path, Sink & sink, bool memory_map)
|
||||
}
|
||||
|
||||
// Stream the file instead if memory-mapping fails or is disabled.
|
||||
AutoCloseFD fd = openFileReadonly(std::filesystem::path(path));
|
||||
auto fd = openFileReadonly(std::filesystem::path(path));
|
||||
if (!fd)
|
||||
throw NativeSysError("opening file %s", PathFmt(path));
|
||||
drainFD(fd.get(), sink);
|
||||
|
||||
@@ -168,14 +168,14 @@ std::filesystem::path descriptorToPath(Descriptor fd);
|
||||
/**
|
||||
* Open a `Descriptor` with read-only access to the given directory.
|
||||
*/
|
||||
Descriptor openDirectory(const std::filesystem::path & path);
|
||||
AutoCloseFD openDirectory(const std::filesystem::path & path);
|
||||
|
||||
/**
|
||||
* Open a `Descriptor` with read-only access to the given file.
|
||||
*
|
||||
* @note For directories use @ref openDirectory.
|
||||
*/
|
||||
Descriptor openFileReadonly(const std::filesystem::path & path);
|
||||
AutoCloseFD openFileReadonly(const std::filesystem::path & path);
|
||||
|
||||
struct OpenNewFileForWriteParams
|
||||
{
|
||||
@@ -198,7 +198,7 @@ struct OpenNewFileForWriteParams
|
||||
*
|
||||
* @todo Reparse points on Windows.
|
||||
*/
|
||||
Descriptor openNewFileForWrite(const std::filesystem::path & path, mode_t mode, OpenNewFileForWriteParams params);
|
||||
AutoCloseFD openNewFileForWrite(const std::filesystem::path & path, mode_t mode, OpenNewFileForWriteParams params);
|
||||
|
||||
/**
|
||||
* Read the contents of a file into a string.
|
||||
|
||||
@@ -153,7 +153,7 @@ ref<NarAccessor> makeLazyNarAccessor(NarListing listing, GetNarBytes getNarBytes
|
||||
|
||||
GetNarBytes seekableGetNarBytes(const std::filesystem::path & path)
|
||||
{
|
||||
AutoCloseFD fd = openFileReadonly(path);
|
||||
auto fd = openFileReadonly(path);
|
||||
if (!fd)
|
||||
throw NativeSysError("opening NAR cache file %s", PathFmt(path));
|
||||
|
||||
|
||||
@@ -23,17 +23,17 @@
|
||||
|
||||
namespace nix {
|
||||
|
||||
Descriptor openDirectory(const std::filesystem::path & path)
|
||||
AutoCloseFD openDirectory(const std::filesystem::path & path)
|
||||
{
|
||||
return open(path.c_str(), O_RDONLY | O_DIRECTORY | O_CLOEXEC);
|
||||
return AutoCloseFD{open(path.c_str(), O_RDONLY | O_DIRECTORY | O_CLOEXEC)};
|
||||
}
|
||||
|
||||
Descriptor openFileReadonly(const std::filesystem::path & path)
|
||||
AutoCloseFD openFileReadonly(const std::filesystem::path & path)
|
||||
{
|
||||
return open(path.c_str(), O_RDONLY | O_CLOEXEC);
|
||||
return AutoCloseFD{open(path.c_str(), O_RDONLY | O_CLOEXEC)};
|
||||
}
|
||||
|
||||
Descriptor openNewFileForWrite(const std::filesystem::path & path, mode_t mode, OpenNewFileForWriteParams params)
|
||||
AutoCloseFD openNewFileForWrite(const std::filesystem::path & path, mode_t mode, OpenNewFileForWriteParams params)
|
||||
{
|
||||
auto flags = O_WRONLY | O_CREAT | O_CLOEXEC;
|
||||
if (params.truncateExisting) {
|
||||
@@ -43,7 +43,7 @@ Descriptor openNewFileForWrite(const std::filesystem::path & path, mode_t mode,
|
||||
} else {
|
||||
flags |= O_EXCL; /* O_CREAT | O_EXCL already ensures that symlinks are not followed. */
|
||||
}
|
||||
return open(path.c_str(), flags, mode);
|
||||
return AutoCloseFD{open(path.c_str(), flags, mode)};
|
||||
}
|
||||
|
||||
std::filesystem::path descriptorToPath(Descriptor fd)
|
||||
|
||||
@@ -23,41 +23,41 @@ void setWriteTime(
|
||||
warn("Changing file times is not yet implemented on Windows, path is %s", PathFmt(path));
|
||||
}
|
||||
|
||||
Descriptor openDirectory(const std::filesystem::path & path)
|
||||
AutoCloseFD openDirectory(const std::filesystem::path & path)
|
||||
{
|
||||
return CreateFileW(
|
||||
return AutoCloseFD{CreateFileW(
|
||||
path.c_str(),
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||
/*lpSecurityAttributes=*/nullptr,
|
||||
OPEN_EXISTING,
|
||||
FILE_FLAG_BACKUP_SEMANTICS,
|
||||
/*hTemplateFile=*/nullptr);
|
||||
/*hTemplateFile=*/nullptr)};
|
||||
}
|
||||
|
||||
Descriptor openFileReadonly(const std::filesystem::path & path)
|
||||
AutoCloseFD openFileReadonly(const std::filesystem::path & path)
|
||||
{
|
||||
return CreateFileW(
|
||||
return AutoCloseFD{CreateFileW(
|
||||
path.c_str(),
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ | FILE_SHARE_DELETE,
|
||||
/*lpSecurityAttributes=*/nullptr,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
/*hTemplateFile=*/nullptr);
|
||||
/*hTemplateFile=*/nullptr)};
|
||||
}
|
||||
|
||||
Descriptor
|
||||
AutoCloseFD
|
||||
openNewFileForWrite(const std::filesystem::path & path, [[maybe_unused]] mode_t mode, OpenNewFileForWriteParams params)
|
||||
{
|
||||
return CreateFileW(
|
||||
return AutoCloseFD{CreateFileW(
|
||||
path.c_str(),
|
||||
GENERIC_WRITE,
|
||||
FILE_SHARE_READ | FILE_SHARE_DELETE,
|
||||
/*lpSecurityAttributes=*/nullptr,
|
||||
params.truncateExisting ? CREATE_ALWAYS : CREATE_NEW, /* TODO: Reparse points. */
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
/*hTemplateFile=*/nullptr);
|
||||
/*hTemplateFile=*/nullptr)};
|
||||
}
|
||||
|
||||
std::filesystem::path defaultTempDir()
|
||||
|
||||
@@ -78,7 +78,7 @@ struct CmdCatNar : StoreCommand, MixCat
|
||||
|
||||
void run(ref<Store> store) override
|
||||
{
|
||||
AutoCloseFD fd = openFileReadonly(narPath);
|
||||
auto fd = openFileReadonly(narPath);
|
||||
if (!fd)
|
||||
throw NativeSysError("opening NAR file %s", PathFmt(narPath));
|
||||
auto source = FdSource{fd.get()};
|
||||
|
||||
@@ -150,7 +150,7 @@ struct CmdLsNar : Command, MixLs
|
||||
|
||||
void run() override
|
||||
{
|
||||
AutoCloseFD fd = openFileReadonly(narPath);
|
||||
auto fd = openFileReadonly(narPath);
|
||||
if (!fd)
|
||||
throw NativeSysError("opening NAR file %s", PathFmt(narPath));
|
||||
auto source = FdSource{fd.get()};
|
||||
|
||||
@@ -45,7 +45,7 @@ static void readChannels()
|
||||
// Writes the list of channels.
|
||||
static void writeChannels()
|
||||
{
|
||||
AutoCloseFD channelsFD = openNewFileForWrite(
|
||||
auto channelsFD = openNewFileForWrite(
|
||||
channelsList,
|
||||
0644,
|
||||
{
|
||||
|
||||
@@ -112,7 +112,7 @@ std::tuple<StorePath, Hash> prefetchFile(
|
||||
if (executable)
|
||||
mode = 0700;
|
||||
|
||||
AutoCloseFD fd = openNewFileForWrite(tmpFile, mode, {.truncateExisting = false});
|
||||
auto fd = openNewFileForWrite(tmpFile, mode, {.truncateExisting = false});
|
||||
if (!fd)
|
||||
throw SysError("creating temporary file %s", PathFmt(tmpFile));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user