summaryrefslogtreecommitdiff
path: root/src/port/win32env.c
diff options
context:
space:
mode:
authorMagnus Hagander2009-01-21 10:30:02 +0000
committerMagnus Hagander2009-01-21 10:30:02 +0000
commit0154345078fb96a8bbe8b8785628400b17e5a75b (patch)
tree34e581ca07428ed44cdc4f4a9d58d7df9f08a501 /src/port/win32env.c
parentfa40ca42a6bc3da349eaf661ef9e25c0064d110d (diff)
Make win32 builds always do SetEnvironmentVariable() when doing putenv().
Also, if linked against other versions than the default MSVCRT library (for example the MSVC build which links against MSVCRT80), also update the cache in the default MSVCRT at the same time. This should fix the issues with setting LC_MESSAGES on the MSVC build. Original patch from Hiroshi Inoue and Hiroshi Saito, much rewritten by me.
Diffstat (limited to 'src/port/win32env.c')
-rw-r--r--src/port/win32env.c93
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);
+}
+