46
40
is then placed in the environment, while the argument of `putenv'
47
41
must be used directly. This is all complicated by the fact that we try
48
42
to reuse values once generated for a `setenv' call since we can never
50
int __add_to_environ (const char *name, const char *value,
51
const char *combined, int replace) attribute_hidden;
52
int __add_to_environ (const char *name, const char *value,
53
const char *combined, int replace)
43
free the strings. [in uclibc, we do not] */
44
static int __add_to_environ(const char *name, const char *value,
57
const size_t namelen = strlen (name);
58
const size_t vallen = value != NULL ? strlen (value) + 1 : 0;
61
__UCLIBC_MUTEX_LOCK(mylock);
63
/* We have to get the pointer now that we have the lock and not earlier
64
since another thread might have created a new environment. */
69
for (; *ep != NULL; ++ep) {
70
if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=')
51
/* name may come from putenv() and thus may contain "=VAL" part */
52
const size_t namelen = strchrnul(name, '=') - name;
55
__UCLIBC_MUTEX_LOCK(mylock);
57
/* We have to get the pointer now that we have the lock and not earlier
58
since another thread might have created a new environment. */
64
if (!strncmp(*ep, name, namelen) && (*ep)[namelen] == '=') {
77
if (ep == NULL || *ep == NULL) {
80
/* We allocated this space; we can extend it. */
81
new_environ = (char **) realloc (last_environ, (size + 2) * sizeof (char *));
82
if (new_environ == NULL) {
75
/* Not found, add at the end */
77
/* We allocated this space; we can extend it. */
78
new_environ = realloc(last_environ, (size + 2) * sizeof(char *));
79
if (new_environ == NULL) {
83
if (__environ != last_environ) {
84
memcpy(new_environ, __environ, size * sizeof(char *));
86
last_environ = __environ = new_environ;
88
ep = &new_environ[size];
89
/* Ensure env is NULL terminated in case malloc below fails */
94
var_val = (char*) name;
95
/* Build VAR=VAL if we called by setenv, not putenv. */
97
const size_t vallen = strlen(value) + 1;
99
var_val = malloc(namelen + 1 + vallen);
100
if (var_val == NULL) {
86
/* If the whole entry is given add it. */
87
if (combined != NULL) {
88
/* We must not add the string to the search tree since it belongs
90
new_environ[size] = (char *) combined;
92
/* See whether the value is already known. */
93
new_environ[size] = (char *) malloc (namelen + 1 + vallen);
94
if (new_environ[size] == NULL) {
99
memcpy (new_environ[size], name, namelen);
100
new_environ[size][namelen] = '=';
101
memcpy (&new_environ[size][namelen + 1], value, vallen);
104
if (__environ != last_environ) {
105
memcpy ((char *) new_environ, (char *) __environ,
106
size * sizeof (char *));
109
new_environ[size + 1] = NULL;
110
last_environ = __environ = new_environ;
111
} else if (replace) {
114
/* Use the user string if given. */
115
if (combined != NULL) {
116
np = (char *) combined;
118
np = malloc (namelen + 1 + vallen);
122
memcpy (np, name, namelen);
124
memcpy (&np[namelen + 1], value, vallen);
104
memcpy(var_val, name, namelen);
105
var_val[namelen] = '=';
106
memcpy(&var_val[namelen + 1], value, vallen);
132
__UCLIBC_MUTEX_UNLOCK(mylock);
114
__UCLIBC_MUTEX_UNLOCK(mylock);
136
libc_hidden_proto(setenv)
137
int setenv (const char *name, const char *value, int replace)
118
int setenv(const char *name, const char *value, int replace)
139
return __add_to_environ (name, value, NULL, replace);
120
/* NB: setenv("VAR", NULL, 1) inserts "VAR=" string */
121
return __add_to_environ(name, value ? value : "", replace);
141
123
libc_hidden_def(setenv)
143
libc_hidden_proto(unsetenv)
144
int unsetenv (const char *name)
125
int unsetenv(const char *name)
149
if (name == NULL || *name == '\0' || strchr (name, '=') != NULL) {
150
__set_errno (EINVAL);
131
if (name == NULL || *name == '\0'
132
|| *(eq = strchrnul(name, '=')) == '='
137
len = eq - name; /* avoiding strlen this way */
155
__UCLIBC_MUTEX_LOCK(mylock);
157
while (*ep != NULL) {
158
if (!strncmp (*ep, name, len) && (*ep)[len] == '=') {
139
__UCLIBC_MUTEX_LOCK(mylock);
141
/* NB: clearenv(); unsetenv("foo"); should not segfault */
142
if (ep) while (*ep != NULL) {
143
if (!strncmp(*ep, name, len) && (*ep)[len] == '=') {
159
144
/* Found it. Remove this pointer by moving later ones back. */
169
__UCLIBC_MUTEX_UNLOCK(mylock);
154
__UCLIBC_MUTEX_UNLOCK(mylock);
172
157
libc_hidden_def(unsetenv)
174
159
/* The `clearenv' was planned to be added to POSIX.1 but probably
175
160
never made it. Nevertheless the POSIX.9 standard (POSIX bindings
176
161
for Fortran 77) requires this function. */
179
__UCLIBC_MUTEX_LOCK(mylock);
180
if (__environ == last_environ && __environ != NULL) {
181
/* We allocated this environment so we can free it. */
185
/* Clear the environment pointer removes the whole environment. */
187
__UCLIBC_MUTEX_UNLOCK(mylock);
164
__UCLIBC_MUTEX_LOCK(mylock);
165
/* If we allocated this environment we can free it.
166
* If we did not allocate this environment, it's NULL already
167
* and is safe to free(). */
170
/* Clearing environ removes the whole environment. */
172
__UCLIBC_MUTEX_UNLOCK(mylock);
191
176
/* Put STRING, which is of the form "NAME=VALUE", in the environment. */
192
int putenv (char *string)
177
int putenv(char *string)
195
const char *const name_end = strchr (string, '=');
197
if (name_end != NULL) {
198
char *name = strndup(string, name_end - string);
199
result = __add_to_environ (name, NULL, string, 1);
179
if (strchr(string, '=') != NULL) {
180
return __add_to_environ(string, NULL, 1);
182
return unsetenv(string);