Initial commit of visual studio 9 git build superproject.
[git-build-vc9.git] / tcrt / src / env.cpp
blob27fcaa8fc6686ef92a2668b5d5533b02510fa036
1 /*=============================================================================
2 env.cpp :
4 Copyright © 2008 Bruno Santos <nayart3@gmail.com>
5 =============================================================================*/
7 #include <stdlib.h>
8 #include "utils.h"
10 ///////////////////////////////////////////////////////////////////////////////
11 namespace {
12 class enviromental {
13 public:
14 enviromental();
15 ~enviromental();
17 void unset(const char* name);
18 char* set(const char* name, const char* value);
19 char* get(const char* name) const;
21 private:
22 struct entry {
23 char *name;
24 char *value;
28 entry* _entries;
29 uint _count;
32 enviromental::enviromental() : _entries(NULL), _count(0)
36 enviromental::~enviromental()
38 for (uint i = 0; i < _count; ++i) {
39 free(_entries[i].name);
40 free(_entries[i].value);
42 free(_entries);
45 char* enviromental::set(const char* name, const char* value)
47 char* nam = strdup(name);
48 if (name == NULL) {
49 errno = ENOMEM;
50 return NULL;
52 char* val = strdup(value);
53 if (value == NULL) {
54 free(nam);
55 errno = ENOMEM;
56 return NULL;
59 for (uint i = 0; i < _count; ++i) {
60 if (!strcmp(_entries[i].name, name)) {
61 free(_entries[i].name);
62 free(_entries[i].value);
63 _entries[i].name = nam;
64 _entries[i].value = val;
65 return val;
69 entry* p = (entry*) realloc(_entries, (_count + 1) * sizeof(entry));
70 if (p == NULL) {
71 free(nam);
72 free(val);
73 errno = ENOMEM;
74 return NULL;
76 _entries = p;
77 _entries[_count].name = nam;
78 _entries[_count].value = val;
79 _count += 1;
80 return val;
83 void enviromental::unset(const char* name)
85 for (uint i = 0; i < _count; ++i) {
86 if (!strcmp(_entries[i].name, name)) {
87 free(_entries[i].name);
88 free(_entries[i].value);
89 i += 1;
90 memmove(_entries + i - 1, _entries + i, _count - i);
91 _count -= 1;
92 break;
97 char* enviromental::get(const char* name) const
99 for (uint i = 0; i < _count; ++i) {
100 if (!strcmp(_entries[i].name, name))
101 return _entries[i].value;
103 return NULL;
106 enviromental env;
107 tcrt::rolock env_lock;
110 ///////////////////////////////////////////////////////////////////////////////
111 int setenv(const char* envname, const char* envval, int overwrite)
113 tcrt::buffer<wchar_t> wnam;
114 tcrt::buffer<wchar_t> wenv;
115 size_t namlen;
116 size_t envlen;
118 namlen = strlen(envname) + 1;
119 envlen = strlen(envval) + 1;
120 if (!wnam.resize(namlen * sizeof(wchar_t)))
121 return -1;
122 if (!wenv.resize(envlen * sizeof(wchar_t)))
123 return -1;
125 tcrt_utf8_to_utf16(envname, namlen, wnam.get(), namlen);
126 tcrt_utf8_to_utf16(envval, envlen, wenv.get(), envlen);
127 if (!overwrite && GetEnvironmentVariable(wnam.get(), NULL, 0)) {
128 errno = EEXIST;
129 return -1;
131 if (!SetEnvironmentVariable(wnam.get(), wenv.get())) {
132 tcrt_set_errno_win32();
133 return -1;
136 tcrt::auto_rolock al(env_lock);
137 return (env.set(envname, envval) == NULL) ? -1 : 0;
140 int unsetenv(const char* name)
142 tcrt::buffer<wchar_t> wnam;
143 size_t len;
145 len = strlen(name) + 1;
146 if (!wnam.resize(len * sizeof(wchar_t)))
147 return -1;
149 tcrt_utf8_to_utf16(name, len, wnam.get(), len);
150 if (!SetEnvironmentVariable(wnam.get(), NULL)) {
151 tcrt_set_errno_win32();
152 return -1;
155 tcrt::auto_rolock al(env_lock);
156 env.unset(name);
157 return 0;
160 char* getenv(const char* name)
162 tcrt::buffer<wchar_t> wname;
163 tcrt::buffer<wchar_t> wenv;
164 tcrt::buffer<char> value;
165 size_t len;
166 char* res;
168 tcrt::auto_rolock al(env_lock);
169 res = env.get(name);
170 if (res != NULL)
171 return res;
173 len = strlen(name) + 1;
174 if (!wname.resize(len * sizeof(wchar_t)))
175 return NULL;
177 tcrt_utf8_to_utf16(name, len, wname.get(), len);
178 len = GetEnvironmentVariableW(wname.get(), NULL, 0);
179 if (len) {
180 if (!wenv.resize(len * sizeof(wchar_t)))
181 return NULL;
183 GetEnvironmentVariableW(wname.get(), wenv.get(), len);
184 if (!value.resize(len * sizeof(wchar_t)))
185 return NULL;
187 tcrt_utf16_to_utf8(wenv.get(), len, value.get(), len * sizeof(wchar_t));
188 return env.set(name, value.get());
190 return NULL;
193 // EOF ////////////////////////////////////////////////////////////////////////