diff --git a/src/libcmd/editor-for.cc b/src/libcmd/editor-for.cc index e5f762104..a56a7065e 100644 --- a/src/libcmd/editor-for.cc +++ b/src/libcmd/editor-for.cc @@ -1,5 +1,6 @@ #include "util.hh" #include "editor-for.hh" +#include "environment-variables.hh" #include "source-path.hh" namespace nix { diff --git a/src/libmain/loggers.cc b/src/libmain/loggers.cc index cda5cb939..7e80a31f1 100644 --- a/src/libmain/loggers.cc +++ b/src/libmain/loggers.cc @@ -1,3 +1,4 @@ +#include "environment-variables.hh" #include "loggers.hh" #include "progress-bar.hh" #include "util.hh" diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc index 3308cad1f..897d3e8ef 100644 --- a/src/libstore/globals.cc +++ b/src/libstore/globals.cc @@ -1,3 +1,4 @@ +#include "environment-variables.hh" #include "globals.hh" #include "util.hh" #include "archive.hh" diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh index 85789f6b5..581de7ff6 100644 --- a/src/libstore/globals.hh +++ b/src/libstore/globals.hh @@ -1,9 +1,9 @@ #pragma once ///@file +#include "environment-variables.hh" #include "types.hh" #include "config.hh" -#include "util.hh" #include #include diff --git a/src/libstore/ssh.cc b/src/libstore/ssh.cc index 87414fe9c..2f921e2d0 100644 --- a/src/libstore/ssh.cc +++ b/src/libstore/ssh.cc @@ -1,3 +1,4 @@ +#include "environment-variables.hh" #include "ssh.hh" #include "finally.hh" diff --git a/src/libutil/args.cc b/src/libutil/args.cc index 520f50c30..bcff653c5 100644 --- a/src/libutil/args.cc +++ b/src/libutil/args.cc @@ -2,6 +2,8 @@ #include "args/root.hh" #include "hash.hh" #include "json-utils.hh" +#include "environment-variables.hh" + #include "experimental-features-json.hh" #include diff --git a/src/libutil/environment-variables.cc b/src/libutil/environment-variables.cc new file mode 100644 index 000000000..71c404a0e --- /dev/null +++ b/src/libutil/environment-variables.cc @@ -0,0 +1,51 @@ +#include +#include +#include +#include + +extern char * * environ __attribute__((weak)); + +namespace nix { + +std::optional getEnv(const std::string & key) +{ + char * value = getenv(key.c_str()); + if (!value) return {}; + return std::string(value); +} + +std::optional getEnvNonEmpty(const std::string & key) { + auto value = getEnv(key); + if (value == "") return {}; + return value; +} + +std::map getEnv() +{ + std::map env; + for (size_t i = 0; environ[i]; ++i) { + auto s = environ[i]; + auto eq = strchr(s, '='); + if (!eq) + // invalid env, just keep going + continue; + env.emplace(std::string(s, eq), std::string(eq + 1)); + } + return env; +} + + +void clearEnv() +{ + for (auto & name : getEnv()) + unsetenv(name.first.c_str()); +} + +void replaceEnv(const std::map & newEnv) +{ + clearEnv(); + for (auto & newEnvVar : newEnv) + setenv(newEnvVar.first.c_str(), newEnvVar.second.c_str(), 1); +} + +} diff --git a/src/libutil/environment-variables.hh b/src/libutil/environment-variables.hh new file mode 100644 index 000000000..784b95921 --- /dev/null +++ b/src/libutil/environment-variables.hh @@ -0,0 +1,42 @@ +#pragma once +/** + * @file + * + * Utilities for working with the current process's environment + * variables. + */ + +#include +#include +#include + + +namespace nix { + +/** + * @return an environment variable. + */ +std::optional getEnv(const std::string & key); + +/** + * @return a non empty environment variable. Returns nullopt if the env + * variable is set to "" + */ +std::optional getEnvNonEmpty(const std::string & key); + +/** + * Get the entire environment. + */ +std::map getEnv(); + +/** + * Clear the environment. + */ +void clearEnv(); + +/** + * Replace the entire environment with the given one. + */ +void replaceEnv(const std::map & newEnv); + +} diff --git a/src/libutil/error.cc b/src/libutil/error.cc index b534ff87e..fe73ffc56 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -1,3 +1,4 @@ +#include "environment-variables.hh" #include "error.hh" #include "position.hh" diff --git a/src/libutil/filesystem.cc b/src/libutil/filesystem.cc index b637281d0..85871870c 100644 --- a/src/libutil/filesystem.cc +++ b/src/libutil/filesystem.cc @@ -2,6 +2,7 @@ #include #include +#include "environment-variables.hh" #include "finally.hh" #include "util.hh" #include "signals.hh" diff --git a/src/libutil/logging.cc b/src/libutil/logging.cc index 0e63f9bd6..8e4828be4 100644 --- a/src/libutil/logging.cc +++ b/src/libutil/logging.cc @@ -1,3 +1,4 @@ +#include "environment-variables.hh" #include "logging.hh" #include "util.hh" #include "config.hh" diff --git a/src/libutil/meson.build b/src/libutil/meson.build index 58e0bd062..01b3e24b7 100644 --- a/src/libutil/meson.build +++ b/src/libutil/meson.build @@ -7,6 +7,7 @@ libutil_sources = files( 'compute-levels.cc', 'config.cc', 'english.cc', + 'environment-variables.cc', 'error.cc', 'escape-char.cc', 'escape-string.cc', @@ -53,6 +54,7 @@ libutil_headers = files( 'config-impl.hh', 'config.hh', 'english.hh', + 'environment-variables.hh', 'error.hh', 'escape-char.hh', 'escape-string.hh', diff --git a/src/libutil/util.cc b/src/libutil/util.cc index 2c0fcc897..97d53ca63 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -4,6 +4,7 @@ #include "serialise.hh" #include "cgroup.hh" #include "signals.hh" +#include "environment-variables.hh" #include #include @@ -43,57 +44,12 @@ #endif -extern char * * environ __attribute__((weak)); - - #ifdef NDEBUG #error "Lix may not be built with assertions disabled (i.e. with -DNDEBUG)." #endif namespace nix { -std::optional getEnv(const std::string & key) -{ - char * value = getenv(key.c_str()); - if (!value) return {}; - return std::string(value); -} - -std::optional getEnvNonEmpty(const std::string & key) { - auto value = getEnv(key); - if (value == "") return {}; - return value; -} - -std::map getEnv() -{ - std::map env; - for (size_t i = 0; environ[i]; ++i) { - auto s = environ[i]; - auto eq = strchr(s, '='); - if (!eq) - // invalid env, just keep going - continue; - env.emplace(std::string(s, eq), std::string(eq + 1)); - } - return env; -} - - -void clearEnv() -{ - for (auto & name : getEnv()) - unsetenv(name.first.c_str()); -} - -void replaceEnv(const std::map & newEnv) -{ - clearEnv(); - for (auto & newEnvVar : newEnv) - setenv(newEnvVar.first.c_str(), newEnvVar.second.c_str(), 1); -} - - Path absPath(Path path, std::optional dir, bool resolveSymlinks) { if (path.empty() || path[0] != '/') { diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 14868776c..151da25b9 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -39,27 +39,6 @@ struct Source; extern const std::string nativeSystem; -/** - * @return an environment variable. - */ -std::optional getEnv(const std::string & key); - -/** - * @return a non empty environment variable. Returns nullopt if the env - * variable is set to "" - */ -std::optional getEnvNonEmpty(const std::string & key); - -/** - * Get the entire environment. - */ -std::map getEnv(); - -/** - * Clear the environment. - */ -void clearEnv(); - /** * @return An absolutized path, resolving paths relative to the * specified directory, or the current directory otherwise. The path diff --git a/tests/unit/libutil-support/tests/characterization.hh b/tests/unit/libutil-support/tests/characterization.hh index 7f570f619..9de20d02c 100644 --- a/tests/unit/libutil-support/tests/characterization.hh +++ b/tests/unit/libutil-support/tests/characterization.hh @@ -1,6 +1,7 @@ #pragma once ///@file +#include "environment-variables.hh" #include #include