summaryrefslogtreecommitdiff
path: root/src/port/win32env.c
diff options
context:
space:
mode:
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);
+}
+