mirror of
https://github.com/NixOS/nix.git
synced 2025-12-05 00:21:01 +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:
parent
3a32039508
commit
4ad272015e
3 changed files with 43 additions and 0 deletions
|
|
@ -381,4 +381,21 @@ TEST(openFileEnsureBeneathNoSymlinks, works)
|
||||||
|
|
||||||
#endif
|
#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
|
} // namespace nix
|
||||||
|
|
|
||||||
|
|
@ -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)
|
std::pair<AutoCloseFD, Path> createTempFile(const Path & prefix)
|
||||||
{
|
{
|
||||||
Path tmpl(defaultTempDir() + "/" + prefix + ".XXXXXX");
|
Path tmpl(defaultTempDir() + "/" + prefix + ".XXXXXX");
|
||||||
// Strictly speaking, this is UB, but who cares...
|
// Strictly speaking, this is UB, but who cares...
|
||||||
// FIXME: use O_TMPFILE.
|
// FIXME: use O_TMPFILE.
|
||||||
|
// FIXME: Windows should use FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE
|
||||||
AutoCloseFD fd = toDescriptor(mkstemp((char *) tmpl.c_str()));
|
AutoCloseFD fd = toDescriptor(mkstemp((char *) tmpl.c_str()));
|
||||||
if (!fd)
|
if (!fd)
|
||||||
throw SysError("creating temporary file '%s'", tmpl);
|
throw SysError("creating temporary file '%s'", tmpl);
|
||||||
|
|
|
||||||
|
|
@ -337,6 +337,12 @@ typedef std::unique_ptr<DIR, DIRDeleter> AutoCloseDir;
|
||||||
std::filesystem::path
|
std::filesystem::path
|
||||||
createTempDir(const std::filesystem::path & tmpRoot = "", const std::string & prefix = "nix", mode_t mode = 0755);
|
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.
|
* Create a temporary file, returning a file handle and its path.
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue