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