OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/environment.h" | 5 #include "base/environment.h" |
6 | 6 |
| 7 #include <stdlib.h> |
7 #include <vector> | 8 #include <vector> |
8 | 9 |
9 #include "base/strings/string_piece.h" | 10 #include "base/strings/string_piece.h" |
10 #include "base/strings/string_util.h" | 11 #include "base/strings/string_util.h" |
11 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
12 | 13 |
13 #if defined(OS_POSIX) | |
14 #include <stdlib.h> | |
15 #elif defined(OS_WIN) | |
16 #include <windows.h> | |
17 #endif | |
18 | |
19 namespace base { | 14 namespace base { |
20 | 15 |
21 namespace { | 16 namespace { |
22 | 17 |
23 class EnvironmentImpl : public Environment { | 18 class EnvironmentImpl : public Environment { |
24 public: | 19 public: |
25 bool GetVar(const char* variable_name, std::string* result) override { | 20 bool GetVar(const char* variable_name, std::string* result) override { |
26 if (GetVarImpl(variable_name, result)) | 21 if (GetVarImpl(variable_name, result)) |
27 return true; | 22 return true; |
28 | 23 |
(...skipping 24 matching lines...) Expand all Loading... |
53 private: | 48 private: |
54 bool GetVarImpl(const char* variable_name, std::string* result) { | 49 bool GetVarImpl(const char* variable_name, std::string* result) { |
55 #if defined(OS_POSIX) | 50 #if defined(OS_POSIX) |
56 const char* env_value = getenv(variable_name); | 51 const char* env_value = getenv(variable_name); |
57 if (!env_value) | 52 if (!env_value) |
58 return false; | 53 return false; |
59 // Note that the variable may be defined but empty. | 54 // Note that the variable may be defined but empty. |
60 if (result) | 55 if (result) |
61 *result = env_value; | 56 *result = env_value; |
62 return true; | 57 return true; |
63 #elif defined(OS_WIN) | |
64 DWORD value_length = ::GetEnvironmentVariable( | |
65 UTF8ToWide(variable_name).c_str(), NULL, 0); | |
66 if (value_length == 0) | |
67 return false; | |
68 if (result) { | |
69 scoped_ptr<wchar_t[]> value(new wchar_t[value_length]); | |
70 ::GetEnvironmentVariable(UTF8ToWide(variable_name).c_str(), value.get(), | |
71 value_length); | |
72 *result = WideToUTF8(value.get()); | |
73 } | |
74 return true; | |
75 #else | 58 #else |
76 #error need to port | 59 #error need to port |
77 #endif | 60 #endif |
78 } | 61 } |
79 | 62 |
80 bool SetVarImpl(const char* variable_name, const std::string& new_value) { | 63 bool SetVarImpl(const char* variable_name, const std::string& new_value) { |
81 #if defined(OS_POSIX) | |
82 // On success, zero is returned. | 64 // On success, zero is returned. |
83 return !setenv(variable_name, new_value.c_str(), 1); | 65 return !setenv(variable_name, new_value.c_str(), 1); |
84 #elif defined(OS_WIN) | |
85 // On success, a nonzero value is returned. | |
86 return !!SetEnvironmentVariable(UTF8ToWide(variable_name).c_str(), | |
87 UTF8ToWide(new_value).c_str()); | |
88 #endif | |
89 } | 66 } |
90 | 67 |
91 bool UnSetVarImpl(const char* variable_name) { | 68 bool UnSetVarImpl(const char* variable_name) { |
92 #if defined(OS_POSIX) | |
93 // On success, zero is returned. | 69 // On success, zero is returned. |
94 return !unsetenv(variable_name); | 70 return !unsetenv(variable_name); |
95 #elif defined(OS_WIN) | |
96 // On success, a nonzero value is returned. | |
97 return !!SetEnvironmentVariable(UTF8ToWide(variable_name).c_str(), NULL); | |
98 #endif | |
99 } | 71 } |
100 }; | 72 }; |
101 | 73 |
102 // Parses a null-terminated input string of an environment block. The key is | 74 // Parses a null-terminated input string of an environment block. The key is |
103 // placed into the given string, and the total length of the line, including | 75 // placed into the given string, and the total length of the line, including |
104 // the terminating null, is returned. | 76 // the terminating null, is returned. |
105 size_t ParseEnvLine(const NativeEnvironmentString::value_type* input, | 77 size_t ParseEnvLine(const NativeEnvironmentString::value_type* input, |
106 NativeEnvironmentString* key) { | 78 NativeEnvironmentString* key) { |
107 // Skip to the equals or end of the string, this is the key. | 79 // Skip to the equals or end of the string, this is the key. |
108 size_t cur = 0; | 80 size_t cur = 0; |
(...skipping 23 matching lines...) Expand all Loading... |
132 | 104 |
133 // static | 105 // static |
134 Environment* Environment::Create() { | 106 Environment* Environment::Create() { |
135 return new EnvironmentImpl(); | 107 return new EnvironmentImpl(); |
136 } | 108 } |
137 | 109 |
138 bool Environment::HasVar(const char* variable_name) { | 110 bool Environment::HasVar(const char* variable_name) { |
139 return GetVar(variable_name, NULL); | 111 return GetVar(variable_name, NULL); |
140 } | 112 } |
141 | 113 |
142 #if defined(OS_WIN) | |
143 | |
144 string16 AlterEnvironment(const wchar_t* env, | |
145 const EnvironmentMap& changes) { | |
146 string16 result; | |
147 | |
148 // First copy all unmodified values to the output. | |
149 size_t cur_env = 0; | |
150 string16 key; | |
151 while (env[cur_env]) { | |
152 const wchar_t* line = &env[cur_env]; | |
153 size_t line_length = ParseEnvLine(line, &key); | |
154 | |
155 // Keep only values not specified in the change vector. | |
156 EnvironmentMap::const_iterator found_change = changes.find(key); | |
157 if (found_change == changes.end()) | |
158 result.append(line, line_length); | |
159 | |
160 cur_env += line_length; | |
161 } | |
162 | |
163 // Now append all modified and new values. | |
164 for (EnvironmentMap::const_iterator i = changes.begin(); | |
165 i != changes.end(); ++i) { | |
166 if (!i->second.empty()) { | |
167 result.append(i->first); | |
168 result.push_back('='); | |
169 result.append(i->second); | |
170 result.push_back(0); | |
171 } | |
172 } | |
173 | |
174 // An additional null marks the end of the list. We always need a double-null | |
175 // in case nothing was added above. | |
176 if (result.empty()) | |
177 result.push_back(0); | |
178 result.push_back(0); | |
179 return result; | |
180 } | |
181 | |
182 #elif defined(OS_POSIX) | |
183 | |
184 scoped_ptr<char*[]> AlterEnvironment(const char* const* const env, | 114 scoped_ptr<char*[]> AlterEnvironment(const char* const* const env, |
185 const EnvironmentMap& changes) { | 115 const EnvironmentMap& changes) { |
186 std::string value_storage; // Holds concatenated null-terminated strings. | 116 std::string value_storage; // Holds concatenated null-terminated strings. |
187 std::vector<size_t> result_indices; // Line indices into value_storage. | 117 std::vector<size_t> result_indices; // Line indices into value_storage. |
188 | 118 |
189 // First build up all of the unchanged environment strings. These are | 119 // First build up all of the unchanged environment strings. These are |
190 // null-terminated of the form "key=value". | 120 // null-terminated of the form "key=value". |
191 std::string key; | 121 std::string key; |
192 for (size_t i = 0; env[i]; i++) { | 122 for (size_t i = 0; env[i]; i++) { |
193 size_t line_length = ParseEnvLine(env[i], &key); | 123 size_t line_length = ParseEnvLine(env[i], &key); |
(...skipping 30 matching lines...) Expand all Loading... |
224 memcpy(storage_data, value_storage.data(), value_storage.size()); | 154 memcpy(storage_data, value_storage.data(), value_storage.size()); |
225 | 155 |
226 // Fill array of pointers at the beginning of the result. | 156 // Fill array of pointers at the beginning of the result. |
227 for (size_t i = 0; i < result_indices.size(); i++) | 157 for (size_t i = 0; i < result_indices.size(); i++) |
228 result[i] = &storage_data[result_indices[i]]; | 158 result[i] = &storage_data[result_indices[i]]; |
229 result[result_indices.size()] = 0; // Null terminator. | 159 result[result_indices.size()] = 0; // Null terminator. |
230 | 160 |
231 return result.Pass(); | 161 return result.Pass(); |
232 } | 162 } |
233 | 163 |
234 #endif // OS_POSIX | |
235 | |
236 } // namespace base | 164 } // namespace base |
OLD | NEW |