fix support for initialized TLS in static PIE binaries
[musl.git] / src / env / putenv.c
blob7153042669da81a80bff37a3c25aeb1618a64da9
1 #include <stdlib.h>
2 #include <string.h>
4 extern char **__environ;
5 char **__env_map;
7 int __putenv(char *s, int a)
9 int i=0, j=0;
10 char *z = strchr(s, '=');
11 char **newenv = 0;
12 char **newmap = 0;
13 static char **oldenv;
15 if (!z) return unsetenv(s);
16 if (z==s) return -1;
17 for (; __environ[i] && memcmp(s, __environ[i], z-s+1); i++);
18 if (a) {
19 if (!__env_map) {
20 __env_map = calloc(2, sizeof(char *));
21 if (__env_map) __env_map[0] = s;
22 } else {
23 for (; __env_map[j] && __env_map[j] != __environ[i]; j++);
24 if (!__env_map[j]) {
25 newmap = realloc(__env_map, sizeof(char *)*(j+2));
26 if (newmap) {
27 __env_map = newmap;
28 __env_map[j] = s;
29 __env_map[j+1] = NULL;
31 } else {
32 free(__env_map[j]);
33 __env_map[j] = s;
37 if (!__environ[i]) {
38 newenv = malloc(sizeof(char *)*(i+2));
39 if (!newenv) {
40 if (a && __env_map) __env_map[j] = 0;
41 return -1;
43 memcpy(newenv, __environ, sizeof(char *)*i);
44 newenv[i] = s;
45 newenv[i+1] = 0;
46 __environ = newenv;
47 free(oldenv);
48 oldenv = __environ;
51 __environ[i] = s;
52 return 0;
55 int putenv(char *s)
57 return __putenv(s, 0);