environment.cc revision 3345a6884c488ff3a535c2c9acdd33d74b37e311
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/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/scoped_ptr.h"
17#include "base/utf_string_conversions.h"
18#endif
19
20namespace {
21
22class 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
102namespace base {
103
104namespace 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/).
109const char kHome[] = "HOME";
110#endif
111
112}  // namespace env_vars
113
114Environment::~Environment() {}
115
116// static
117Environment* Environment::Create() {
118  return new EnvironmentImpl();
119}
120
121bool Environment::HasVar(const char* variable_name) {
122  return GetVar(variable_name, NULL);
123}
124
125}  // namespace base
126