1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-12-04 08:00:59 +01:00

libutil: Implement createAnonymousTempFile

There are a lot of cases where we don't care about having
the temporary file linked anywhere at all -- just a descriptor is more
than enough.
This commit is contained in:
Sergei Zimmerman 2025-12-01 04:21:05 +03:00
parent 3a32039508
commit 4ad272015e
No known key found for this signature in database
3 changed files with 43 additions and 0 deletions

View file

@ -381,4 +381,21 @@ TEST(openFileEnsureBeneathNoSymlinks, works)
#endif
/* ----------------------------------------------------------------------------
* createAnonymousTempFile
* --------------------------------------------------------------------------*/
TEST(createAnonymousTempFile, works)
{
auto fd = createAnonymousTempFile();
writeFull(fd.get(), "test");
lseek(fd.get(), 0, SEEK_SET);
FdSource source{fd.get()};
EXPECT_EQ(source.drain(), "test");
lseek(fd.get(), 0, SEEK_END);
writeFull(fd.get(), "test");
lseek(fd.get(), 0, SEEK_SET);
EXPECT_EQ(source.drain(), "testtest");
}
} // namespace nix

View file

@ -713,11 +713,31 @@ std::filesystem::path createTempDir(const std::filesystem::path & tmpRoot, const
}
}
AutoCloseFD createAnonymousTempFile()
{
AutoCloseFD fd;
#ifdef O_TMPFILE
fd = ::open(defaultTempDir().c_str(), O_TMPFILE | O_CLOEXEC | O_RDWR, S_IWUSR | S_IRUSR);
if (!fd)
throw SysError("creating anonymous temporary file");
#else
auto [fd2, path] = createTempFile("nix-anonymous");
if (!fd2)
throw SysError("creating temporary file '%s'", path);
fd = std::move(fd2);
# ifndef _WIN32
unlink(requireCString(path)); /* We only care about the file descriptor. */
# endif
#endif
return fd;
}
std::pair<AutoCloseFD, Path> createTempFile(const Path & prefix)
{
Path tmpl(defaultTempDir() + "/" + prefix + ".XXXXXX");
// Strictly speaking, this is UB, but who cares...
// FIXME: use O_TMPFILE.
// FIXME: Windows should use FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE
AutoCloseFD fd = toDescriptor(mkstemp((char *) tmpl.c_str()));
if (!fd)
throw SysError("creating temporary file '%s'", tmpl);

View file

@ -337,6 +337,12 @@ typedef std::unique_ptr<DIR, DIRDeleter> AutoCloseDir;
std::filesystem::path
createTempDir(const std::filesystem::path & tmpRoot = "", const std::string & prefix = "nix", mode_t mode = 0755);
/**
* Create an anonymous readable/writable temporary file, returning a file handle.
* On UNIX there resulting file isn't linked to any path on the filesystem.
*/
AutoCloseFD createAnonymousTempFile();
/**
* Create a temporary file, returning a file handle and its path.
*/