summaryrefslogtreecommitdiff
path: root/libc/stdlib
diff options
context:
space:
mode:
Diffstat (limited to 'libc/stdlib')
-rw-r--r--libc/stdlib/setenv.c74
1 files changed, 38 insertions, 36 deletions
diff --git a/libc/stdlib/setenv.c b/libc/stdlib/setenv.c
index 3011f34a9..6598a6c52 100644
--- a/libc/stdlib/setenv.c
+++ b/libc/stdlib/setenv.c
@@ -52,6 +52,8 @@ static int __add_to_environ(const char *name, const char *value,
{
register char **ep;
register size_t size;
+ char *var_val;
+ char **new_environ;
/* name may come from putenv() and thus may contain "=VAL" part */
const size_t namelen = strchrnul(name, '=') - name;
int rv = -1;
@@ -64,54 +66,54 @@ static int __add_to_environ(const char *name, const char *value,
size = 0;
if (ep != NULL) {
- for (; *ep != NULL; ++ep) {
- if (!strncmp(*ep, name, namelen) && (*ep)[namelen] == '=')
- break;
+ while (*ep != NULL) {
+ if (!strncmp(*ep, name, namelen) && (*ep)[namelen] == '=') {
+ /* Found */
+ if (!replace)
+ goto DONE_OK;
+ goto REPLACE;
+ }
++size;
+ ++ep;
}
}
- if (ep == NULL || *ep == NULL) {
- /* Not found, add at the end */
- char **new_environ;
+ /* Not found, add at the end */
- /* We allocated this space; we can extend it. */
- new_environ = realloc(last_environ, (size + 2) * sizeof(char *));
- if (new_environ == NULL) {
- __set_errno(ENOMEM);
- goto DONE;
- }
- if (__environ != last_environ) {
- memcpy(new_environ, __environ, size * sizeof(char *));
- }
- last_environ = __environ = new_environ;
-
- ep = &new_environ[size];
- /* Ensure env is NULL terminated in case malloc below fails */
- ep[0] = NULL;
- ep[1] = NULL;
- replace = 1;
+ /* We allocated this space; we can extend it. */
+ new_environ = realloc(last_environ, (size + 2) * sizeof(char *));
+ if (new_environ == NULL) {
+ __set_errno(ENOMEM);
+ goto DONE;
+ }
+ if (__environ != last_environ) {
+ memcpy(new_environ, __environ, size * sizeof(char *));
}
+ last_environ = __environ = new_environ;
- if (replace) {
- char *var_val = (char*) name;
+ ep = &new_environ[size];
+ /* Ensure env is NULL terminated in case malloc below fails */
+ ep[0] = NULL;
+ ep[1] = NULL;
- /* Build VAR=VAL if we called by setenv, not putenv. */
- if (value != NULL) {
- const size_t vallen = strlen(value) + 1;
+ REPLACE:
+ var_val = (char*) name;
+ /* Build VAR=VAL if we called by setenv, not putenv. */
+ if (value != NULL) {
+ const size_t vallen = strlen(value) + 1;
- var_val = malloc(namelen + 1 + vallen);
- if (var_val == NULL) {
- __set_errno(ENOMEM);
- goto DONE;
- }
- memcpy(var_val, name, namelen);
- var_val[namelen] = '=';
- memcpy(&var_val[namelen + 1], value, vallen);
+ var_val = malloc(namelen + 1 + vallen);
+ if (var_val == NULL) {
+ __set_errno(ENOMEM);
+ goto DONE;
}
- *ep = var_val;
+ memcpy(var_val, name, namelen);
+ var_val[namelen] = '=';
+ memcpy(&var_val[namelen + 1], value, vallen);
}
+ *ep = var_val;
+ DONE_OK:
rv = 0;
DONE: