aboutsummaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
Diffstat (limited to 'win32')
-rw-r--r--win32/env.c126
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
3static 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
17char *mingw_getenv(const char *name) 6char *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)
29int setenv(const char *name, const char *value, int replace) 18int 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 */
65char **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 43int unsetenv(const char *name)
104int 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
117int clearenv(void) 60int 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
150void unsetenv(const char *env)
151{
152 env_setenv(environ, env);
153}
154
155int 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