environment.cc 3.6 KB

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