Home | History | Annotate | Download | only in base
      1 // Copyright (c) 2011 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/environment.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/memory/scoped_ptr.h"
     17 #include "base/utf_string_conversions.h"
     18 #endif
     19 
     20 namespace {
     21 
     22 class EnvironmentImpl : public base::Environment {
     23  public:
     24   virtual bool GetVar(const char* variable_name, std::string* result) {
     25     if (GetVarImpl(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 GetVarImpl(alternate_case_var.c_str(), result);
     41   }
     42 
     43   virtual bool SetVar(const char* variable_name, const std::string& new_value) {
     44     return SetVarImpl(variable_name, new_value);
     45   }
     46 
     47   virtual bool UnSetVar(const char* variable_name) {
     48     return UnSetVarImpl(variable_name);
     49   }
     50 
     51  private:
     52   bool GetVarImpl(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   }
     77 
     78   bool SetVarImpl(const char* variable_name, const std::string& new_value) {
     79 #if defined(OS_POSIX)
     80     // On success, zero is returned.
     81     return !setenv(variable_name, new_value.c_str(), 1);
     82 #elif defined(OS_WIN)
     83     // On success, a nonzero value is returned.
     84     return !!SetEnvironmentVariable(UTF8ToWide(variable_name).c_str(),
     85                                     UTF8ToWide(new_value).c_str());
     86 #endif
     87   }
     88 
     89   bool UnSetVarImpl(const char* variable_name) {
     90 #if defined(OS_POSIX)
     91     // On success, zero is returned.
     92     return !unsetenv(variable_name);
     93 #elif defined(OS_WIN)
     94     // On success, a nonzero value is returned.
     95     return !!SetEnvironmentVariable(UTF8ToWide(variable_name).c_str(), NULL);
     96 #endif
     97   }
     98 };
     99 
    100 }  // namespace
    101 
    102 namespace base {
    103 
    104 namespace env_vars {
    105 
    106 #if defined(OS_POSIX)
    107 // On Posix systems, this variable contains the location of the user's home
    108 // directory. (e.g, /home/username/).
    109 const char kHome[] = "HOME";
    110 #endif
    111 
    112 }  // namespace env_vars
    113 
    114 Environment::~Environment() {}
    115 
    116 // static
    117 Environment* Environment::Create() {
    118   return new EnvironmentImpl();
    119 }
    120 
    121 bool Environment::HasVar(const char* variable_name) {
    122   return GetVar(variable_name, NULL);
    123 }
    124 
    125 }  // namespace base
    126