Treat empty env var paths as unset

We make sure the env var paths are actually set (ie. not "") before
sending them to the canonicalization function. If we forget to do so,
the user will end up facing a puzzled failed assertion internal error.

We issue a non-failing warning as a stop-gap measure. We could want to
revisit this to issue a detailed failing error message in the future.
This commit is contained in:
Félix Baylac Jacqué 2023-03-01 20:01:36 +01:00 committed by zimbatm
parent 4489def1b3
commit 25300c0ecd
No known key found for this signature in database
GPG key ID: 71BAF6D40C1D63D7
4 changed files with 24 additions and 8 deletions

View file

@ -2063,7 +2063,7 @@ void LocalDerivationGoal::runChild()
/* The tmpDir in scope points at the temporary build directory for our derivation. Some packages try different mechanisms /* 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. */ to find temporary directories, so we want to open up a broader place for them to dump their files, if needed. */
Path globalTmpDir = canonPath(getEnv("TMPDIR").value_or("/tmp"), true); Path globalTmpDir = canonPath(getEnvNonEmpty("TMPDIR").value_or("/tmp"), true);
/* They don't like trailing slashes on subpath directives */ /* They don't like trailing slashes on subpath directives */
if (globalTmpDir.back() == '/') globalTmpDir.pop_back(); if (globalTmpDir.back() == '/') globalTmpDir.pop_back();

View file

@ -30,15 +30,15 @@ static GlobalConfig::Register rSettings(&settings);
Settings::Settings() Settings::Settings()
: nixPrefix(NIX_PREFIX) : nixPrefix(NIX_PREFIX)
, nixStore(canonPath(getEnv("NIX_STORE_DIR").value_or(getEnv("NIX_STORE").value_or(NIX_STORE_DIR)))) , nixStore(canonPath(getEnvNonEmpty("NIX_STORE_DIR").value_or(getEnvNonEmpty("NIX_STORE").value_or(NIX_STORE_DIR))))
, nixDataDir(canonPath(getEnv("NIX_DATA_DIR").value_or(NIX_DATA_DIR))) , nixDataDir(canonPath(getEnvNonEmpty("NIX_DATA_DIR").value_or(NIX_DATA_DIR)))
, nixLogDir(canonPath(getEnv("NIX_LOG_DIR").value_or(NIX_LOG_DIR))) , nixLogDir(canonPath(getEnvNonEmpty("NIX_LOG_DIR").value_or(NIX_LOG_DIR)))
, nixStateDir(canonPath(getEnv("NIX_STATE_DIR").value_or(NIX_STATE_DIR))) , nixStateDir(canonPath(getEnvNonEmpty("NIX_STATE_DIR").value_or(NIX_STATE_DIR)))
, nixConfDir(canonPath(getEnv("NIX_CONF_DIR").value_or(NIX_CONF_DIR))) , nixConfDir(canonPath(getEnvNonEmpty("NIX_CONF_DIR").value_or(NIX_CONF_DIR)))
, nixUserConfFiles(getUserConfigFiles()) , nixUserConfFiles(getUserConfigFiles())
, nixBinDir(canonPath(getEnv("NIX_BIN_DIR").value_or(NIX_BIN_DIR))) , nixBinDir(canonPath(getEnvNonEmpty("NIX_BIN_DIR").value_or(NIX_BIN_DIR)))
, nixManDir(canonPath(NIX_MAN_DIR)) , nixManDir(canonPath(NIX_MAN_DIR))
, nixDaemonSocketFile(canonPath(getEnv("NIX_DAEMON_SOCKET_PATH").value_or(nixStateDir + DEFAULT_SOCKET_PATH))) , nixDaemonSocketFile(canonPath(getEnvNonEmpty("NIX_DAEMON_SOCKET_PATH").value_or(nixStateDir + DEFAULT_SOCKET_PATH)))
{ {
buildUsersGroup = getuid() == 0 ? "nixbld" : ""; buildUsersGroup = getuid() == 0 ? "nixbld" : "";
lockCPU = getEnv("NIX_AFFINITY_HACK") == "1"; lockCPU = getEnv("NIX_AFFINITY_HACK") == "1";

View file

@ -54,6 +54,18 @@ std::optional<std::string> getEnv(const std::string & key)
return std::string(value); return std::string(value);
} }
std::optional<std::string> getEnvNonEmpty(const std::string & key) {
auto value = getEnv(key);
if (value == "") {
// TODO: determine whether this should be a warning or an error.
logWarning({
.msg = hintfmt("ignoring the '%1%' env variable, its value has been set to \"\"", key)
});
return std::nullopt;
} else {
return value;
}
}
std::map<std::string, std::string> getEnv() std::map<std::string, std::string> getEnv()
{ {

View file

@ -39,6 +39,10 @@ extern const std::string nativeSystem;
/* Return an environment variable. */ /* Return an environment variable. */
std::optional<std::string> getEnv(const std::string & key); std::optional<std::string> getEnv(const std::string & key);
/* Return a non empty environment variable. Returns nullopt if the env
variable is set to "" */
std::optional<std::string> getEnvNonEmpty(const std::string & key);
/* Get the entire environment. */ /* Get the entire environment. */
std::map<std::string, std::string> getEnv(); std::map<std::string, std::string> getEnv();