diff options
-rw-r--r-- | include/mingw.h | 8 | ||||
-rw-r--r-- | win32/Kbuild | 1 | ||||
-rw-r--r-- | win32/env.c | 119 |
3 files changed, 124 insertions, 4 deletions
diff --git a/include/mingw.h b/include/mingw.h index c2c0c7816..32a9b4b4a 100644 --- a/include/mingw.h +++ b/include/mingw.h | |||
@@ -129,12 +129,12 @@ int fdprintf(int fd, const char *format, ...); | |||
129 | #define WIFSIGNALED(x) ((unsigned)(x) > 259) | 129 | #define WIFSIGNALED(x) ((unsigned)(x) > 259) |
130 | #define WTERMSIG(x) ((x) & 0x7f) | 130 | #define WTERMSIG(x) ((x) & 0x7f) |
131 | 131 | ||
132 | NOIMPL(clearenv,void); | 132 | int clearenv(void); |
133 | IMPL(mingw_getenv,char*,NULL,const char *name UNUSED_PARAM); | 133 | char *mingw_getenv(const char *name); |
134 | int mkstemp(char *template); | 134 | int mkstemp(char *template); |
135 | char *realpath(const char *path, char *resolved_path); | 135 | char *realpath(const char *path, char *resolved_path); |
136 | NOIMPL(setenv,const char *name UNUSED_PARAM, const char *value UNUSED_PARAM, int replace UNUSED_PARAM); | 136 | int setenv(const char *name, const char *value, int replace); |
137 | IMPL(unsetenv,void,,const char *env UNUSED_PARAM); | 137 | void unsetenv(const char *env); |
138 | 138 | ||
139 | #define getenv mingw_getenv | 139 | #define getenv mingw_getenv |
140 | /* | 140 | /* |
diff --git a/win32/Kbuild b/win32/Kbuild index 22f8252d0..878330fc3 100644 --- a/win32/Kbuild +++ b/win32/Kbuild | |||
@@ -4,6 +4,7 @@ | |||
4 | 4 | ||
5 | lib-y:= | 5 | lib-y:= |
6 | 6 | ||
7 | lib-$(CONFIG_PLATFORM_MINGW32) += env.o | ||
7 | lib-$(CONFIG_PLATFORM_MINGW32) += fnmatch.o | 8 | lib-$(CONFIG_PLATFORM_MINGW32) += fnmatch.o |
8 | lib-$(CONFIG_PLATFORM_MINGW32) += mingw.o | 9 | lib-$(CONFIG_PLATFORM_MINGW32) += mingw.o |
9 | lib-$(CONFIG_PLATFORM_MINGW32) += process.o | 10 | lib-$(CONFIG_PLATFORM_MINGW32) += process.o |
diff --git a/win32/env.c b/win32/env.c new file mode 100644 index 000000000..376ad9d47 --- /dev/null +++ b/win32/env.c | |||
@@ -0,0 +1,119 @@ | |||
1 | #include "libbb.h" | ||
2 | |||
3 | char **copy_environ(const char *const *envp) | ||
4 | { | ||
5 | char **env; | ||
6 | int i = 0; | ||
7 | while (envp[i]) | ||
8 | i++; | ||
9 | env = xmalloc((i+1)*sizeof(*env)); | ||
10 | for (i = 0; envp[i]; i++) | ||
11 | env[i] = xstrdup(envp[i]); | ||
12 | env[i] = NULL; | ||
13 | return env; | ||
14 | } | ||
15 | |||
16 | void free_environ(char **env) | ||
17 | { | ||
18 | int i; | ||
19 | for (i = 0; env[i]; i++) | ||
20 | free(env[i]); | ||
21 | free(env); | ||
22 | } | ||
23 | |||
24 | static int lookup_env(char **env, const char *name, size_t nmln) | ||
25 | { | ||
26 | int i; | ||
27 | |||
28 | for (i = 0; env[i]; i++) { | ||
29 | if (0 == strncmp(env[i], name, nmln) | ||
30 | && '=' == env[i][nmln]) | ||
31 | /* matches */ | ||
32 | return i; | ||
33 | } | ||
34 | return -1; | ||
35 | } | ||
36 | |||
37 | #undef getenv | ||
38 | char *mingw_getenv(const char *name) | ||
39 | { | ||
40 | char *result = getenv(name); | ||
41 | if (!result && !strcmp(name, "TMPDIR")) { | ||
42 | /* on Windows it is TMP and TEMP */ | ||
43 | result = getenv("TMP"); | ||
44 | if (!result) | ||
45 | result = getenv("TEMP"); | ||
46 | } | ||
47 | return result; | ||
48 | } | ||
49 | |||
50 | int setenv(const char *name, const char *value, int replace) | ||
51 | { | ||
52 | int out; | ||
53 | size_t namelen, valuelen; | ||
54 | char *envstr; | ||
55 | |||
56 | if (!name || !value) return -1; | ||
57 | if (!replace) { | ||
58 | char *oldval = NULL; | ||
59 | oldval = getenv(name); | ||
60 | if (oldval) return 0; | ||
61 | } | ||
62 | |||
63 | namelen = strlen(name); | ||
64 | valuelen = strlen(value); | ||
65 | envstr = malloc((namelen + valuelen + 2)); | ||
66 | if (!envstr) return -1; | ||
67 | |||
68 | memcpy(envstr, name, namelen); | ||
69 | envstr[namelen] = '='; | ||
70 | memcpy(envstr + namelen + 1, value, valuelen); | ||
71 | envstr[namelen + valuelen + 1] = 0; | ||
72 | |||
73 | out = putenv(envstr); | ||
74 | /* putenv(3) makes the argument string part of the environment, | ||
75 | * and changing that string modifies the environment --- which | ||
76 | * means we do not own that storage anymore. Do not free | ||
77 | * envstr. | ||
78 | */ | ||
79 | |||
80 | return out; | ||
81 | } | ||
82 | |||
83 | /* | ||
84 | * If name contains '=', then sets the variable, otherwise it unsets it | ||
85 | */ | ||
86 | char **env_setenv(char **env, const char *name) | ||
87 | { | ||
88 | char *eq = strchrnul(name, '='); | ||
89 | int i = lookup_env(env, name, eq-name); | ||
90 | |||
91 | if (i < 0) { | ||
92 | if (*eq) { | ||
93 | for (i = 0; env[i]; i++) | ||
94 | ; | ||
95 | env = xrealloc(env, (i+2)*sizeof(*env)); | ||
96 | env[i] = xstrdup(name); | ||
97 | env[i+1] = NULL; | ||
98 | } | ||
99 | } | ||
100 | else { | ||
101 | free(env[i]); | ||
102 | if (*eq) | ||
103 | env[i] = xstrdup(name); | ||
104 | else | ||
105 | for (; env[i]; i++) | ||
106 | env[i] = env[i+1]; | ||
107 | } | ||
108 | return env; | ||
109 | } | ||
110 | |||
111 | void unsetenv(const char *env) | ||
112 | { | ||
113 | env_setenv(environ, env); | ||
114 | } | ||
115 | |||
116 | int clearenv(void) | ||
117 | { | ||
118 | bb_error_msg_and_die("clearenv() is not supported"); | ||
119 | } | ||