1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
base / environment.cc [blame]
// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/environment.h"
#include <array>
#include <string_view>
#include "base/memory/ptr_util.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#if BUILDFLAG(IS_WIN)
#include <windows.h>
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
#include <stdlib.h>
#endif
namespace base {
namespace {
class EnvironmentImpl : public Environment {
public:
bool GetVar(std::string_view variable_name, std::string* result) override {
if (GetVarImpl(variable_name, result))
return true;
// Some commonly used variable names are uppercase while others
// are lowercase, which is inconsistent. Let's try to be helpful
// and look for a variable name with the reverse case.
// I.e. HTTP_PROXY may be http_proxy for some users/systems.
char first_char = variable_name[0];
std::string alternate_case_var;
if (IsAsciiLower(first_char))
alternate_case_var = ToUpperASCII(variable_name);
else if (IsAsciiUpper(first_char))
alternate_case_var = ToLowerASCII(variable_name);
else
return false;
return GetVarImpl(alternate_case_var, result);
}
bool SetVar(std::string_view variable_name,
const std::string& new_value) override {
return SetVarImpl(variable_name, new_value);
}
bool UnSetVar(std::string_view variable_name) override {
return UnSetVarImpl(variable_name);
}
private:
bool GetVarImpl(std::string_view variable_name, std::string* result) {
#if BUILDFLAG(IS_WIN)
std::wstring wide_name = UTF8ToWide(variable_name);
if (!result) {
return ::GetEnvironmentVariable(wide_name.c_str(), nullptr, 0) != 0;
}
// Documented to be the maximum environment variable size.
std::array<wchar_t, 32767> value;
DWORD value_length =
::GetEnvironmentVariable(wide_name.c_str(), value.data(), value.size());
if (value_length == 0) {
return false;
}
CHECK_LE(value_length, value.size() - 1)
<< "value should fit in the buffer (including the null terminator)";
WideToUTF8(value.data(), value_length, result);
return true;
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
const char* env_value = getenv(std::string(variable_name).c_str());
if (!env_value)
return false;
// Note that the variable may be defined but empty.
if (result)
*result = env_value;
return true;
#endif
}
bool SetVarImpl(std::string_view variable_name,
const std::string& new_value) {
#if BUILDFLAG(IS_WIN)
// On success, a nonzero value is returned.
return !!SetEnvironmentVariable(UTF8ToWide(variable_name).c_str(),
UTF8ToWide(new_value).c_str());
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
// On success, zero is returned.
return !setenv(variable_name.data(), new_value.c_str(), 1);
#endif
}
bool UnSetVarImpl(std::string_view variable_name) {
#if BUILDFLAG(IS_WIN)
// On success, a nonzero value is returned.
return !!SetEnvironmentVariable(UTF8ToWide(variable_name).c_str(), nullptr);
#elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
// On success, zero is returned.
return !unsetenv(variable_name.data());
#endif
}
};
} // namespace
namespace env_vars {
#if BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
// On Posix systems, this variable contains the location of the user's home
// directory. (e.g, /home/username/).
const char kHome[] = "HOME";
#endif
} // namespace env_vars
Environment::~Environment() = default;
// static
std::unique_ptr<Environment> Environment::Create() {
return std::make_unique<EnvironmentImpl>();
}
bool Environment::HasVar(std::string_view variable_name) {
return GetVar(variable_name, nullptr);
}
} // namespace base