Skip to content

Commit

Permalink
fix: Treat empty TMPDIR as unset
Browse files Browse the repository at this point in the history
Fixes an instance of

    nix: src/libutil/util.cc:139: nix::Path nix::canonPath(PathView, bool): Assertion `path != ""' failed.

... which I've been getting in one of my shells for some reason.
I have yet to find out why TMPDIR was empty, but it's no reason for
Nix to break.
  • Loading branch information
roberth committed Mar 22, 2024
1 parent a223280 commit ee547d5
Show file tree
Hide file tree
Showing 4 changed files with 14 additions and 4 deletions.
2 changes: 1 addition & 1 deletion src/libstore/globals.cc
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ void initLibStore() {
sshd). This breaks build users because they don't have access
to the TMPDIR, in particular in ‘nix-store --serve’. */
#if __APPLE__
if (hasPrefix(getEnv("TMPDIR").value_or("/tmp"), "/var/folders/"))
if (defaultTempDir(), "/var/folders/"))
unsetenv("TMPDIR");
#endif

Expand Down
10 changes: 8 additions & 2 deletions src/libutil/file-system.cc
Original file line number Diff line number Diff line change
Expand Up @@ -494,10 +494,16 @@ void AutoDelete::reset(const Path & p, bool recursive) {

//////////////////////////////////////////////////////////////////////

std::string defaultTempDir() {
constexpr auto def = "/tmp";
auto dir = getEnv("TMPDIR").value_or(def);
return dir.empty() ? def : dir;
}

static Path tempName(Path tmpRoot, const Path & prefix, bool includePid,
std::atomic<unsigned int> & counter)
{
tmpRoot = canonPath(tmpRoot.empty() ? getEnv("TMPDIR").value_or("/tmp") : tmpRoot, true);
tmpRoot = canonPath(tmpRoot.empty() ? defaultTempDir() : tmpRoot, true);
if (includePid)
return fmt("%1%/%2%-%3%-%4%", tmpRoot, prefix, getpid(), counter++);
else
Expand Down Expand Up @@ -537,7 +543,7 @@ Path createTempDir(const Path & tmpRoot, const Path & prefix,

std::pair<AutoCloseFD, Path> createTempFile(const Path & prefix)
{
Path tmpl(getEnv("TMPDIR").value_or("/tmp") + "/" + prefix + ".XXXXXX");
Path tmpl(defaultTempDir() + "/" + prefix + ".XXXXXX");
// Strictly speaking, this is UB, but who cares...
// FIXME: use O_TMPFILE.
AutoCloseFD fd(mkstemp((char *) tmpl.c_str()));
Expand Down
4 changes: 4 additions & 0 deletions src/libutil/file-system.hh
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,10 @@ Path createTempDir(const Path & tmpRoot = "", const Path & prefix = "nix",
*/
std::pair<AutoCloseFD, Path> createTempFile(const Path & prefix = "nix");

/**
* Return `TMPDIR`, or the default temporary directory if unset or empty.
*/
Path defaultTempDir();

/**
* Used in various places.
Expand Down
2 changes: 1 addition & 1 deletion src/nix-build/nix-build.cc
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,7 @@ static void main_nix_build(int argc, char * * argv)
auto env = getEnv();

auto tmp = getEnv("TMPDIR");
if (!tmp) tmp = getEnv("XDG_RUNTIME_DIR").value_or("/tmp");
if (!tmp || tmp->empty()) tmp = getEnv("XDG_RUNTIME_DIR").value_or("/tmp");

if (pure) {
decltype(env) newEnv;
Expand Down

0 comments on commit ee547d5

Please sign in to comment.