20f96022ab4c73248c8544def02b1bf9ba5968e0
[musl] / src / env / putenv.c
1 #include <stdlib.h>
2 #include <string.h>
3 #include <unistd.h>
4 #include "libc.h"
5
6 static void dummy(char *old, char *new) {}
7 weak_alias(dummy, __env_rm_add);
8
9 int __putenv(char *s, size_t l, char *r)
10 {
11         size_t i=0;
12         if (__environ) {
13                 for (char **e = __environ; *e; e++, i++)
14                         if (!strncmp(s, *e, l+1)) {
15                                 char *tmp = *e;
16                                 *e = s;
17                                 __env_rm_add(tmp, r);
18                                 return 0;
19                         }
20         }
21         static char **oldenv;
22         char **newenv;
23         if (__environ == oldenv) {
24                 newenv = realloc(oldenv, sizeof *newenv * (i+2));
25                 if (!newenv) goto oom;
26         } else {
27                 newenv = malloc(sizeof *newenv * (i+2));
28                 if (!newenv) goto oom;
29                 if (i) memcpy(newenv, __environ, sizeof *newenv * i);
30                 free(oldenv);
31         }
32         newenv[i] = s;
33         newenv[i+1] = 0;
34         __environ = oldenv = newenv;
35         if (r) __env_rm_add(0, r);
36         return 0;
37 oom:
38         free(r);
39         return -1;
40 }
41
42 int putenv(char *s)
43 {
44         size_t l = __strchrnul(s, '=') - s;
45         if (!l || !s[l]) return unsetenv(s);
46         return __putenv(s, l, 0);
47 }