diff options
Diffstat (limited to 'win32')
-rw-r--r-- | win32/env.c | 126 |
1 files changed, 26 insertions, 100 deletions
diff --git a/win32/env.c b/win32/env.c index eab3c1708..2837c0720 100644 --- a/win32/env.c +++ b/win32/env.c | |||
@@ -1,19 +1,8 @@ | |||
1 | #include "libbb.h" | 1 | #include "libbb.h" |
2 | 2 | ||
3 | static int lookup_env(char **env, const char *name, size_t nmln) | ||
4 | { | ||
5 | int i; | ||
6 | |||
7 | for (i = 0; env[i]; i++) { | ||
8 | if (0 == strncmp(env[i], name, nmln) | ||
9 | && '=' == env[i][nmln]) | ||
10 | /* matches */ | ||
11 | return i; | ||
12 | } | ||
13 | return -1; | ||
14 | } | ||
15 | |||
16 | #undef getenv | 3 | #undef getenv |
4 | #undef putenv | ||
5 | |||
17 | char *mingw_getenv(const char *name) | 6 | char *mingw_getenv(const char *name) |
18 | { | 7 | { |
19 | char *result = getenv(name); | 8 | char *result = getenv(name); |
@@ -29,70 +18,21 @@ char *mingw_getenv(const char *name) | |||
29 | int setenv(const char *name, const char *value, int replace) | 18 | int setenv(const char *name, const char *value, int replace) |
30 | { | 19 | { |
31 | int out; | 20 | int out; |
32 | size_t namelen, valuelen; | ||
33 | char *envstr; | 21 | char *envstr; |
34 | 22 | ||
35 | if (!name || !value) return -1; | 23 | if (!name || !*name || strchr(name, '=') || !value) return -1; |
36 | if (!replace) { | 24 | if (!replace) { |
37 | char *oldval = NULL; | 25 | if (getenv(name)) return 0; |
38 | oldval = getenv(name); | ||
39 | if (oldval) return 0; | ||
40 | } | 26 | } |
41 | 27 | ||
42 | namelen = strlen(name); | 28 | envstr = xasprintf("%s=%s", name, value); |
43 | valuelen = strlen(value); | 29 | out = mingw_putenv(envstr); |
44 | envstr = malloc((namelen + valuelen + 2)); | 30 | free(envstr); |
45 | if (!envstr) return -1; | ||
46 | |||
47 | memcpy(envstr, name, namelen); | ||
48 | envstr[namelen] = '='; | ||
49 | memcpy(envstr + namelen + 1, value, valuelen); | ||
50 | envstr[namelen + valuelen + 1] = 0; | ||
51 | |||
52 | out = putenv(envstr); | ||
53 | /* putenv(3) makes the argument string part of the environment, | ||
54 | * and changing that string modifies the environment --- which | ||
55 | * means we do not own that storage anymore. Do not free | ||
56 | * envstr. | ||
57 | */ | ||
58 | 31 | ||
59 | return out; | 32 | return out; |
60 | } | 33 | } |
61 | 34 | ||
62 | /* | 35 | /* |
63 | * If name contains '=', then sets the variable, otherwise it unsets it | ||
64 | */ | ||
65 | char **env_setenv(char **env, const char *name) | ||
66 | { | ||
67 | char *eq = strchrnul(name, '='); | ||
68 | int i = lookup_env(env, name, eq-name); | ||
69 | |||
70 | if (i < 0) { | ||
71 | if (*eq) { | ||
72 | for (i = 0; env[i]; i++) | ||
73 | ; | ||
74 | env = xrealloc(env, (i+2)*sizeof(*env)); | ||
75 | env[i] = xstrdup(name); | ||
76 | env[i+1] = NULL; | ||
77 | } | ||
78 | } | ||
79 | else { | ||
80 | free(env[i]); | ||
81 | if (*eq) | ||
82 | env[i] = xstrdup(name); | ||
83 | else { | ||
84 | for (; env[i]; i++) | ||
85 | env[i] = env[i+1]; | ||
86 | #if !ENABLE_SAFE_ENV | ||
87 | SetEnvironmentVariable(name, NULL); | ||
88 | #endif | ||
89 | } | ||
90 | } | ||
91 | return env; | ||
92 | } | ||
93 | |||
94 | #if ENABLE_SAFE_ENV | ||
95 | /* | ||
96 | * Removing an environment variable with WIN32 putenv requires an argument | 36 | * Removing an environment variable with WIN32 putenv requires an argument |
97 | * like "NAME="; glibc omits the '='. The implementations of unsetenv and | 37 | * like "NAME="; glibc omits the '='. The implementations of unsetenv and |
98 | * clearenv allow for this. | 38 | * clearenv allow for this. |
@@ -100,28 +40,34 @@ char **env_setenv(char **env, const char *name) | |||
100 | * It isn't possible to create an environment variable with an empty value | 40 | * It isn't possible to create an environment variable with an empty value |
101 | * using WIN32 putenv. | 41 | * using WIN32 putenv. |
102 | */ | 42 | */ |
103 | #undef putenv | 43 | int unsetenv(const char *name) |
104 | int unsetenv(const char *env) | ||
105 | { | 44 | { |
106 | char *name; | 45 | char *envstr; |
107 | int ret; | 46 | int ret; |
108 | 47 | ||
109 | name = xmalloc(strlen(env)+2); | 48 | if (!name || !*name || strchr(name, '=') ) { |
110 | strcat(strcpy(name, env), "="); | 49 | return -1; |
111 | ret = putenv(name); | 50 | } |
112 | free(name); | 51 | |
52 | envstr = xmalloc(strlen(name)+2); | ||
53 | strcat(strcpy(envstr, name), "="); | ||
54 | ret = putenv(envstr); | ||
55 | free(envstr); | ||
113 | 56 | ||
114 | return ret; | 57 | return ret; |
115 | } | 58 | } |
116 | 59 | ||
117 | int clearenv(void) | 60 | int clearenv(void) |
118 | { | 61 | { |
119 | char *name, *s; | 62 | char *envp, *name, *s; |
120 | 63 | ||
121 | while ( environ && *environ ) { | 64 | while ( environ && (envp=*environ) ) { |
122 | if ( (s=strchr(*environ, '=')) != NULL ) { | 65 | if ( (s=strchr(envp, '=')) != NULL ) { |
123 | name = xstrndup(*environ, s-*environ+1); | 66 | name = xstrndup(envp, s-envp+1); |
124 | putenv(name); | 67 | if ( putenv(name) == -1 ) { |
68 | free(name); | ||
69 | return -1; | ||
70 | } | ||
125 | free(name); | 71 | free(name); |
126 | } | 72 | } |
127 | else { | 73 | else { |
@@ -146,23 +92,3 @@ int mingw_putenv(const char *env) | |||
146 | /* can't set empty value */ | 92 | /* can't set empty value */ |
147 | return 0; | 93 | return 0; |
148 | } | 94 | } |
149 | #else | ||
150 | void unsetenv(const char *env) | ||
151 | { | ||
152 | env_setenv(environ, env); | ||
153 | } | ||
154 | |||
155 | int clearenv(void) | ||
156 | { | ||
157 | char **env = environ; | ||
158 | if (!env) | ||
159 | return 0; | ||
160 | while (*env) { | ||
161 | free(*env); | ||
162 | env++; | ||
163 | } | ||
164 | free(env); | ||
165 | environ = NULL; | ||
166 | return 0; | ||
167 | } | ||
168 | #endif | ||