blocxx
EnvVars.cpp
Go to the documentation of this file.
1 /*******************************************************************************
2 * Copyright (C) 2005 Novell, Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * - Redistributions of source code must retain the above copyright notice,
8 * this list of conditions and the following disclaimer.
9 *
10 * - Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 *
14 * - Neither the name of Novell, Inc., nor the names of its
15 * contributors may be used to endorse or promote products derived from this
16 * software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL Novell, Inc., OR THE
22 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *******************************************************************************/
30 
35 #include "blocxx/BLOCXX_config.h"
36 #include "blocxx/EnvVars.hpp"
37 #include "blocxx/Environ.hpp"
38 
39 #include <algorithm>
40 #include <cstring>
41 
42 namespace BLOCXX_NAMESPACE
43 {
44 
45 namespace
46 {
47 
48 void getKeyValue(
49  const char *const strArg,
50  String& key,
51  String& value)
52 {
53  key.erase();
54  value.erase();
55 
56  const char* p = ::strchr(strArg, '=');
57  if(p)
58  {
59  key = String(strArg, size_t(p-strArg));
60  value = p+1;
61  }
62 }
63 
64 inline bool isValidKey(const String &key)
65 {
66  //
67  // SUSv3 specifies that the setenv() function shall fail,
68  // if the environment variable name is NULL, empty or
69  // contains a '=' character:
70  //
71  return key.length() && key.indexOf('=') == String::npos;
72 }
73 
74 } // End of anonymous namespace
75 
78  : m_envMap()
79  , m_envp(0)
80 {
81  if(flag == E_CURRENT_ENVIRONMENT)
82  {
84  }
85 }
86 
88 EnvVars::EnvVars(const char* const envp[])
89  : m_envMap()
90  , m_envp(0)
91 {
92  fillEnvMap(envp, m_envMap);
93 }
94 
97 {
98  deleteEnvp();
99 }
100 
102 // STATIC
103 void
105 {
106  fillEnvMap(environ, envMap);
107 }
108 
110 // STATIC
111 void
112 EnvVars::fillEnvMap(const char* const envp[], EnvMap& envMap)
113 {
114  envMap.clear();
115  String key, value;
116  for(size_t i = 0; envp[i]; i++)
117  {
118  getKeyValue(envp[i], key, value);
119  if(isValidKey(key))
120  {
121  envMap[key] = value;
122  }
123  }
124 }
125 
127 void
129 {
130  if(m_envp)
131  {
132  int i;
133 
134  // Delete all char pointers env var array
135  for(i = 0; m_envp[i]; i++)
136  {
137  // m_envp[i] may be null if deleteEnvp was called because an
138  // exception was caught while trying to allocate the array
139  // in getenvp()
140  delete [] m_envp[i];
141  }
142 
143  delete [] m_envp; // Delete pointer array
144  m_envp = 0;
145  }
146 }
147 
149 String
151  const String& notFoundRetVal) const
152 {
154  return (it != m_envMap.end()) ? it->second : notFoundRetVal;
155 }
156 
158 const char* const*
160 {
161  if(!m_envp)
162  {
163  int i;
164  m_envp = new char* [m_envMap.size()+1];
165  std::fill(m_envp, m_envp+m_envMap.size()+1, (char*)0);
166  try
167  {
169  for(i = 0; it != m_envMap.end(); i++, it++)
170  {
171  size_t klen = it->first.length();
172  size_t vlen = it->second.length();
173 
174  m_envp[i] = new char[klen + vlen + 2];
175  ::strcpy(m_envp[i], it->first.c_str());
176  m_envp[i][klen] = '=';
177  ::strcpy(m_envp[i]+klen+1, it->second.c_str());
178  }
179  }
180  catch(...)
181  {
182  deleteEnvp(); // Delete what has been allocated thus far.
183  throw; // Re-throw this exception
184  }
185  }
186 
187  return m_envp;
188 }
189 
191 bool
192 EnvVars::removeVar(const String& varName)
193 {
194  bool cc = false;
195  EnvMap::iterator it = m_envMap.find(varName);
196  if (it != m_envMap.end())
197  {
198  cc = true;
199  deleteEnvp();
200  m_envMap.erase(it);
201  }
202 
203  return cc;
204 }
205 
207 bool
208 EnvVars::addVar(const String& name, const String& value)
209 {
210  bool cc = false;
211  if(isValidKey(name) && m_envMap.find(name) == m_envMap.end())
212  {
213  cc = true;
214  deleteEnvp();
215  m_envMap[name] = value;
216  }
217  return cc;
218 }
219 
221 bool
222 EnvVars::setVar(const String& key, const String& value)
223 {
224  bool cc = false;
225  if( isValidKey(key))
226  {
227  cc = true;
228  deleteEnvp();
229  m_envMap[key] = value;
230  }
231  return cc;
232 }
233 
235 bool
236 EnvVars::setVar(const String& keyValue)
237 {
238  String key, value;
239  getKeyValue(keyValue.c_str(), key, value);
240  return setVar(key, value);
241 }
242 
244 bool
245 EnvVars::updateVar(const String& name, const String& value)
246 {
247  bool cc = false;
248  EnvMap::iterator it = m_envMap.find(name);
249  if (it != m_envMap.end())
250  {
251  cc = true;
252  deleteEnvp();
253  it->second = value;
254  }
255 
256  return cc;
257 }
258 
259 } // End of BLOCXX_NAMESPACE