Skip to content

Commit

Permalink
Merge pull request #10303 from hercules-ci/fix-empty-TMPDIR
Browse files Browse the repository at this point in the history
fix: Treat empty TMPDIR as unset
  • Loading branch information
edolstra committed Mar 25, 2024
2 parents 641b0bd + 3b7f2bf commit 6d90287
Show file tree
Hide file tree
Showing 7 changed files with 19 additions and 8 deletions.
5 changes: 3 additions & 2 deletions src/libstore/build/local-derivation-goal.cc
Expand Up @@ -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";
Expand Down
2 changes: 1 addition & 1 deletion src/libstore/globals.cc
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 (hasPrefix(defaultTempDir(), "/var/folders/"))
unsetenv("TMPDIR");
#endif

Expand Down
2 changes: 1 addition & 1 deletion src/libstore/http-binary-cache-store.cc
Expand Up @@ -49,7 +49,7 @@ class HttpBinaryCacheStore : public virtual HttpBinaryCacheStoreConfig, public v
, BinaryCacheStore(params)
, cacheUri(scheme + "://" + _cacheUri)
{
if (cacheUri.back() == '/')
while (!cacheUri.empty() && cacheUri.back() == '/')
cacheUri.pop_back();

diskCache = getNarInfoDiskCache();
Expand Down
8 changes: 6 additions & 2 deletions src/libutil/file-system.cc
Expand Up @@ -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<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 +541,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
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
1 change: 1 addition & 0 deletions src/libutil/git.cc
Expand Up @@ -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();
}
Expand Down
5 changes: 3 additions & 2 deletions src/nix-build/nix-build.cc
Expand Up @@ -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;
Expand Down

0 comments on commit 6d90287

Please sign in to comment.