[email protected] | 9bc8cff | 2010-04-03 01:05:39 | [diff] [blame] | 1 | // Copyright (c) 2010 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 | |
| 5 | #include "base/env_var.h" |
| 6 | |
| 7 | #if defined(OS_POSIX) |
| 8 | #include <stdlib.h> |
| 9 | #elif defined(OS_WIN) |
| 10 | #include <windows.h> |
| 11 | #endif |
| 12 | |
| 13 | #include "base/string_util.h" |
| 14 | |
| 15 | #if defined(OS_WIN) |
| 16 | #include "base/scoped_ptr.h" |
| 17 | #include "base/utf_string_conversions.h" |
| 18 | #endif |
| 19 | |
| 20 | namespace { |
| 21 | |
[email protected] | ac7264c | 2010-07-08 13:32:51 | [diff] [blame] | 22 | class EnvVarGetterImpl : public base::EnvVarGetter { |
[email protected] | 9bc8cff | 2010-04-03 01:05:39 | [diff] [blame] | 23 | public: |
| 24 | virtual bool GetEnv(const char* variable_name, std::string* result) { |
| 25 | if (GetEnvImpl(variable_name, result)) |
| 26 | return true; |
| 27 | |
| 28 | // Some commonly used variable names are uppercase while others |
| 29 | // are lowercase, which is inconsistent. Let's try to be helpful |
| 30 | // and look for a variable name with the reverse case. |
| 31 | // I.e. HTTP_PROXY may be http_proxy for some users/systems. |
| 32 | char first_char = variable_name[0]; |
| 33 | std::string alternate_case_var; |
| 34 | if (first_char >= 'a' && first_char <= 'z') |
| 35 | alternate_case_var = StringToUpperASCII(std::string(variable_name)); |
| 36 | else if (first_char >= 'A' && first_char <= 'Z') |
| 37 | alternate_case_var = StringToLowerASCII(std::string(variable_name)); |
| 38 | else |
| 39 | return false; |
| 40 | return GetEnvImpl(alternate_case_var.c_str(), result); |
| 41 | } |
[email protected] | ac7264c | 2010-07-08 13:32:51 | [diff] [blame] | 42 | |
[email protected] | e9032c6 | 2010-07-16 03:34:25 | [diff] [blame] | 43 | virtual bool SetEnv(const char* variable_name, const std::string& new_value) { |
| 44 | return SetEnvImpl(variable_name, new_value); |
[email protected] | ac7264c | 2010-07-08 13:32:51 | [diff] [blame] | 45 | } |
| 46 | |
[email protected] | fc586c7 | 2010-07-31 16:55:40 | [diff] [blame^] | 47 | virtual bool UnSetEnv(const char* variable_name) { |
| 48 | return UnSetEnvImpl(variable_name); |
| 49 | } |
| 50 | |
[email protected] | 9bc8cff | 2010-04-03 01:05:39 | [diff] [blame] | 51 | private: |
| 52 | bool GetEnvImpl(const char* variable_name, std::string* result) { |
| 53 | #if defined(OS_POSIX) |
| 54 | const char* env_value = getenv(variable_name); |
| 55 | if (!env_value) |
| 56 | return false; |
| 57 | // Note that the variable may be defined but empty. |
| 58 | if (result) |
| 59 | *result = env_value; |
| 60 | return true; |
| 61 | #elif defined(OS_WIN) |
| 62 | DWORD value_length = ::GetEnvironmentVariable( |
| 63 | UTF8ToWide(variable_name).c_str(), NULL, 0); |
| 64 | if (value_length == 0) |
| 65 | return false; |
| 66 | if (result) { |
| 67 | scoped_array<wchar_t> value(new wchar_t[value_length]); |
| 68 | ::GetEnvironmentVariable(UTF8ToWide(variable_name).c_str(), value.get(), |
| 69 | value_length); |
| 70 | *result = WideToUTF8(value.get()); |
| 71 | } |
| 72 | return true; |
| 73 | #else |
| 74 | #error need to port |
| 75 | #endif |
| 76 | } |
[email protected] | ac7264c | 2010-07-08 13:32:51 | [diff] [blame] | 77 | |
[email protected] | e9032c6 | 2010-07-16 03:34:25 | [diff] [blame] | 78 | bool SetEnvImpl(const char* variable_name, const std::string& new_value) { |
[email protected] | ac7264c | 2010-07-08 13:32:51 | [diff] [blame] | 79 | #if defined(OS_POSIX) |
[email protected] | e9032c6 | 2010-07-16 03:34:25 | [diff] [blame] | 80 | // On success, zero is returned. |
| 81 | return setenv(variable_name, new_value.c_str(), 1) == 0; |
[email protected] | ac7264c | 2010-07-08 13:32:51 | [diff] [blame] | 82 | #elif defined(OS_WIN) |
[email protected] | e9032c6 | 2010-07-16 03:34:25 | [diff] [blame] | 83 | // On success, a nonzero is returned. |
| 84 | return ::SetEnvironmentVariable(ASCIIToWide(variable_name).c_str(), |
| 85 | ASCIIToWide(new_value).c_str()) != 0; |
[email protected] | ac7264c | 2010-07-08 13:32:51 | [diff] [blame] | 86 | #endif |
| 87 | } |
[email protected] | fc586c7 | 2010-07-31 16:55:40 | [diff] [blame^] | 88 | |
| 89 | bool UnSetEnvImpl(const char* variable_name) { |
| 90 | #if defined(OS_POSIX) |
| 91 | // On success, zero is returned. |
| 92 | return unsetenv(variable_name) == 0; |
| 93 | #elif defined(OS_WIN) |
| 94 | // On success, a nonzero is returned. |
| 95 | return ::SetEnvironmentVariable(ASCIIToWide(variable_name).c_str(), |
| 96 | NULL) != 0; |
| 97 | #endif |
| 98 | } |
[email protected] | 9bc8cff | 2010-04-03 01:05:39 | [diff] [blame] | 99 | }; |
| 100 | |
| 101 | } // namespace |
| 102 | |
| 103 | namespace base { |
| 104 | |
[email protected] | 574f6f0c | 2010-07-21 02:59:28 | [diff] [blame] | 105 | namespace env_vars { |
| 106 | |
| 107 | #if defined(OS_POSIX) |
| 108 | // On Posix systems, this variable contains the location of the user's home |
| 109 | // directory. (e.g, /home/username/). |
| 110 | const char kHome[] = "HOME"; |
| 111 | #endif |
| 112 | |
| 113 | } // namespace env_vars |
| 114 | |
[email protected] | 3a3d4747 | 2010-07-15 21:03:54 | [diff] [blame] | 115 | EnvVarGetter::~EnvVarGetter() {} |
| 116 | |
[email protected] | 9bc8cff | 2010-04-03 01:05:39 | [diff] [blame] | 117 | // static |
| 118 | EnvVarGetter* EnvVarGetter::Create() { |
| 119 | return new EnvVarGetterImpl(); |
| 120 | } |
| 121 | |
[email protected] | fc586c7 | 2010-07-31 16:55:40 | [diff] [blame^] | 122 | bool EnvVarGetter::HasEnv(const char* variable_name) { |
| 123 | return GetEnv(variable_name, NULL); |
| 124 | } |
| 125 | |
[email protected] | 9bc8cff | 2010-04-03 01:05:39 | [diff] [blame] | 126 | } // namespace base |