123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- #include "env.h"
- #include <util/generic/maybe.h>
- #include <util/generic/string.h>
- #include <util/generic/yexception.h>
- #ifdef _win_
- #include <util/generic/vector.h>
- #include "winint.h"
- #else
- #include <cerrno>
- #include <cstdlib>
- #endif
- /**
- * On Windows there may be many copies of enviroment variables, there at least two known, one is
- * manipulated by Win32 API, another by C runtime, so we must be consistent in the choice of
- * functions used to manipulate them.
- *
- * Relevant links:
- * - http://bugs.python.org/issue16633
- * - https://a.yandex-team.ru/review/108892/details
- */
- TMaybe<TString> TryGetEnv(const TString& key) {
- #ifdef _win_
- size_t len = GetEnvironmentVariableA(key.data(), nullptr, 0);
- if (len == 0) {
- if (GetLastError() == ERROR_ENVVAR_NOT_FOUND) {
- return Nothing();
- }
- return TString{};
- }
- TVector<char> buffer(len);
- size_t bufferSize;
- do {
- bufferSize = buffer.size();
- len = GetEnvironmentVariableA(key.data(), buffer.data(), static_cast<DWORD>(bufferSize));
- if (len > bufferSize) {
- buffer.resize(len);
- }
- } while (len > bufferSize);
- return TString(buffer.data(), len);
- #else
- const char* env = getenv(key.data());
- if (!env) {
- return Nothing();
- }
- return TString(env);
- #endif
- }
- TString GetEnv(const TString& key, const TString& def) {
- TMaybe<TString> value = TryGetEnv(key);
- if (value.Defined()) {
- return *std::move(value);
- }
- return def;
- }
- void SetEnv(const TString& key, const TString& value) {
- bool isOk = false;
- int errorCode = 0;
- #ifdef _win_
- isOk = SetEnvironmentVariable(key.data(), value.data());
- if (!isOk) {
- errorCode = GetLastError();
- }
- #else
- isOk = (0 == setenv(key.data(), value.data(), true /*replace*/));
- if (!isOk) {
- errorCode = errno;
- }
- #endif
- Y_ENSURE_EX(isOk, TSystemError() << "failed to SetEnv with error-code " << errorCode);
- }
- void UnsetEnv(const TString& key) {
- bool notFound = false;
- #ifdef _win_
- bool ok = SetEnvironmentVariable(key.c_str(), NULL);
- notFound = !ok && (GetLastError() == ERROR_ENVVAR_NOT_FOUND);
- #else
- bool ok = (0 == unsetenv(key.c_str()));
- #if defined(_darwin_)
- notFound = !ok && (errno == EINVAL);
- #endif
- #endif
- Y_ENSURE_EX(ok || notFound, TSystemError() << "failed to unset environment variable " << key.Quote());
- }
|