From e2d49ee805ab0e6db6f6c787e9c8d31123b7ee65 Mon Sep 17 00:00:00 2001 From: Nguyễn Thái Ngọc Duy Date: Wed, 14 Apr 2010 02:15:27 +0200 Subject: win32: add getenv(), setenv(), unsetenv() and clearenv() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit clearenv() is not supported yet. Signed-off-by: Nguyễn Thái Ngọc Duy --- include/mingw.h | 8 ++-- win32/Kbuild | 1 + win32/env.c | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 124 insertions(+), 4 deletions(-) create mode 100644 win32/env.c diff --git a/include/mingw.h b/include/mingw.h index 08e1aed48..ea70313ff 100644 --- a/include/mingw.h +++ b/include/mingw.h @@ -130,12 +130,12 @@ int fdprintf(int fd, const char *format, ...); #define WIFSIGNALED(x) ((unsigned)(x) > 259) #define WTERMSIG(x) ((x) & 0x7f) -NOIMPL(clearenv,void); -IMPL(mingw_getenv,char*,NULL,const char *name UNUSED_PARAM); +int clearenv(void); +char *mingw_getenv(const char *name); int mkstemp(char *template); char *realpath(const char *path, char *resolved_path); -NOIMPL(setenv,const char *name UNUSED_PARAM, const char *value UNUSED_PARAM, int replace UNUSED_PARAM); -IMPL(unsetenv,void,,const char *env UNUSED_PARAM); +int setenv(const char *name, const char *value, int replace); +void unsetenv(const char *env); #define getenv mingw_getenv /* diff --git a/win32/Kbuild b/win32/Kbuild index 22f8252d0..878330fc3 100644 --- a/win32/Kbuild +++ b/win32/Kbuild @@ -4,6 +4,7 @@ lib-y:= +lib-$(CONFIG_PLATFORM_MINGW32) += env.o lib-$(CONFIG_PLATFORM_MINGW32) += fnmatch.o lib-$(CONFIG_PLATFORM_MINGW32) += mingw.o 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 @@ +#include "libbb.h" + +char **copy_environ(const char *const *envp) +{ + char **env; + int i = 0; + while (envp[i]) + i++; + env = xmalloc((i+1)*sizeof(*env)); + for (i = 0; envp[i]; i++) + env[i] = xstrdup(envp[i]); + env[i] = NULL; + return env; +} + +void free_environ(char **env) +{ + int i; + for (i = 0; env[i]; i++) + free(env[i]); + free(env); +} + +static int lookup_env(char **env, const char *name, size_t nmln) +{ + int i; + + for (i = 0; env[i]; i++) { + if (0 == strncmp(env[i], name, nmln) + && '=' == env[i][nmln]) + /* matches */ + return i; + } + return -1; +} + +#undef getenv +char *mingw_getenv(const char *name) +{ + char *result = getenv(name); + if (!result && !strcmp(name, "TMPDIR")) { + /* on Windows it is TMP and TEMP */ + result = getenv("TMP"); + if (!result) + result = getenv("TEMP"); + } + return result; +} + +int setenv(const char *name, const char *value, int replace) +{ + int out; + size_t namelen, valuelen; + char *envstr; + + if (!name || !value) return -1; + if (!replace) { + char *oldval = NULL; + oldval = getenv(name); + if (oldval) return 0; + } + + namelen = strlen(name); + valuelen = strlen(value); + envstr = malloc((namelen + valuelen + 2)); + if (!envstr) return -1; + + memcpy(envstr, name, namelen); + envstr[namelen] = '='; + memcpy(envstr + namelen + 1, value, valuelen); + envstr[namelen + valuelen + 1] = 0; + + out = putenv(envstr); + /* putenv(3) makes the argument string part of the environment, + * and changing that string modifies the environment --- which + * means we do not own that storage anymore. Do not free + * envstr. + */ + + return out; +} + +/* + * If name contains '=', then sets the variable, otherwise it unsets it + */ +char **env_setenv(char **env, const char *name) +{ + char *eq = strchrnul(name, '='); + int i = lookup_env(env, name, eq-name); + + if (i < 0) { + if (*eq) { + for (i = 0; env[i]; i++) + ; + env = xrealloc(env, (i+2)*sizeof(*env)); + env[i] = xstrdup(name); + env[i+1] = NULL; + } + } + else { + free(env[i]); + if (*eq) + env[i] = xstrdup(name); + else + for (; env[i]; i++) + env[i] = env[i+1]; + } + return env; +} + +void unsetenv(const char *env) +{ + env_setenv(environ, env); +} + +int clearenv(void) +{ + bb_error_msg_and_die("clearenv() is not supported"); +} -- cgit v1.2.3-55-g6feb