diff --git a/src/libstore/build/local-derivation-goal.cc b/src/libstore/build/local-derivation-goal.cc index a9b6a8dbf..612434e4d 100644 --- a/src/libstore/build/local-derivation-goal.cc +++ b/src/libstore/build/local-derivation-goal.cc @@ -2090,10 +2090,11 @@ void LocalDerivationGoal::runChild() /* The tmpDir in scope points at the temporary build directory for our derivation. Some packages try different mechanisms to find temporary directories, so we want to open up a broader place for them to dump their files, if needed. */ - Path globalTmpDir = canonPath(getEnvNonEmpty("TMPDIR").value_or("/tmp"), true); + Path globalTmpDir = canonPath(defaultTempDir(), true); /* They don't like trailing slashes on subpath directives */ - if (globalTmpDir.back() == '/') globalTmpDir.pop_back(); + while (!globalTmpDir.empty() && globalTmpDir.back() == '/') + globalTmpDir.pop_back(); if (getEnv("_NIX_TEST_NO_SANDBOX") != "1") { builder = "/usr/bin/sandbox-exec"; diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc index d22ae4ca0..fa0938d7b 100644 --- a/src/libstore/globals.cc +++ b/src/libstore/globals.cc @@ -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 (hasPrefix(defaultTempDir(), "/var/folders/")) unsetenv("TMPDIR"); #endif diff --git a/src/libstore/http-binary-cache-store.cc b/src/libstore/http-binary-cache-store.cc index 85c5eed4c..5da87e935 100644 --- a/src/libstore/http-binary-cache-store.cc +++ b/src/libstore/http-binary-cache-store.cc @@ -49,7 +49,7 @@ public: , BinaryCacheStore(params) , cacheUri(scheme + "://" + _cacheUri) { - if (cacheUri.back() == '/') + while (!cacheUri.empty() && cacheUri.back() == '/') cacheUri.pop_back(); diskCache = getNarInfoDiskCache(); diff --git a/src/libutil/file-system.cc b/src/libutil/file-system.cc index 9dd6a5133..9f81ee452 100644 --- a/src/libutil/file-system.cc +++ b/src/libutil/file-system.cc @@ -494,10 +494,14 @@ void AutoDelete::reset(const Path & p, bool recursive) { ////////////////////////////////////////////////////////////////////// +std::string defaultTempDir() { + return getEnvNonEmpty("TMPDIR").value_or("/tmp"); +} + static Path tempName(Path tmpRoot, const Path & prefix, bool includePid, std::atomic & 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 @@ -537,7 +541,7 @@ Path createTempDir(const Path & tmpRoot, const Path & prefix, std::pair 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())); diff --git a/src/libutil/file-system.hh b/src/libutil/file-system.hh index 963265e34..9d565c881 100644 --- a/src/libutil/file-system.hh +++ b/src/libutil/file-system.hh @@ -234,6 +234,10 @@ Path createTempDir(const Path & tmpRoot = "", const Path & prefix = "nix", */ std::pair createTempFile(const Path & prefix = "nix"); +/** + * Return `TMPDIR`, or the default temporary directory if unset or empty. + */ +Path defaultTempDir(); /** * Used in various places. diff --git a/src/libutil/git.cc b/src/libutil/git.cc index 0b6e35222..a60589baa 100644 --- a/src/libutil/git.cc +++ b/src/libutil/git.cc @@ -251,6 +251,7 @@ void dumpTree(const Tree & entries, Sink & sink, for (auto & [name, entry] : entries) { auto name2 = name; if (entry.mode == Mode::Directory) { + assert(!name2.empty()); assert(name2.back() == '/'); name2.pop_back(); } diff --git a/src/nix-build/nix-build.cc b/src/nix-build/nix-build.cc index a372e4b1c..35eef5b83 100644 --- a/src/nix-build/nix-build.cc +++ b/src/nix-build/nix-build.cc @@ -475,8 +475,9 @@ static void main_nix_build(int argc, char * * argv) // Set the environment. auto env = getEnv(); - auto tmp = getEnv("TMPDIR"); - if (!tmp) tmp = getEnv("XDG_RUNTIME_DIR").value_or("/tmp"); + auto tmp = getEnvNonEmpty("TMPDIR"); + if (!tmp) + tmp = getEnvNonEmpty("XDG_RUNTIME_DIR").value_or("/tmp"); if (pure) { decltype(env) newEnv;