diff options
Diffstat (limited to 'src/port/win32env.c')
-rw-r--r-- | src/port/win32env.c | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/src/port/win32env.c b/src/port/win32env.c new file mode 100644 index 00000000000..7533549608c --- /dev/null +++ b/src/port/win32env.c @@ -0,0 +1,93 @@ +/*------------------------------------------------------------------------- + * + * win32env.c + * putenv() and unsetenv() for win32, that updates both process + * environment and the cached versions in (potentially multiple) + * MSVCRT. + * + * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * $PostgreSQL: pgsql/src/port/win32env.c,v 1.1 2009/01/21 10:30:02 mha Exp $ + * + *------------------------------------------------------------------------- + */ + +#include "c.h" + +int +pgwin32_putenv(const char *envval) +{ + char *envcpy; + char *cp; + + /* + * Each version of MSVCRT has its own _putenv() call in the runtime + * library. + * + * If we're in VC 7.0 or later (means != mingw), update in + * the 6.0 MSVCRT.DLL environment as well, to work with third party + * libraries linked against it (such as gnuwin32 libraries). + */ +#if defined(_MSC_VER) && (_MSC_VER >= 1300) + typedef int (_cdecl *PUTENVPROC)(const char *); + HMODULE hmodule; + static PUTENVPROC putenvFunc = NULL; + int ret; + + if (putenvFunc == NULL) + { + hmodule = GetModuleHandle("msvcrt"); + if (hmodule == NULL) + return 1; + putenvFunc = (PUTENVPROC)GetProcAddress(hmodule, "_putenv"); + if (putenvFunc == NULL) + return 1; + } + ret = putenvFunc(envval); + if (ret != 0) + return ret; +#endif /* _MSC_VER >= 1300 */ + + + /* + * Update the process environment - to make modifications visible + * to child processes. + * + * Need a copy of the string so we can modify it. + */ + envcpy = strdup(envval); + cp = strchr(envcpy, '='); + if (cp == NULL) + return -1; + *cp = '\0'; + cp++; + if (strlen(cp) == 0) + cp = NULL; + if (!SetEnvironmentVariable(envcpy, cp)) + { + free(envcpy); + return -1; + } + free(envcpy); + + /* Finally, update our "own" cache */ + return _putenv(envval); +} + +void +pgwin32_unsetenv(const char *name) +{ + char *envbuf; + + envbuf = (char *) malloc(strlen(name)+2); + if (!envbuf) + return; + + sprintf(envbuf, "%s=", name); + pgwin32_putenv(envbuf); + free(envbuf); +} + |