]> granicus.if.org Git - postgresql/blob - src/port/win32env.c
8.4 pgindent run, with new combined Linux/FreeBSD/MinGW typedef list
[postgresql] / src / port / win32env.c
1 /*-------------------------------------------------------------------------
2  *
3  * win32env.c
4  *        putenv() and unsetenv() for win32, that updates both process
5  *        environment and the cached versions in (potentially multiple)
6  *        MSVCRT.
7  *
8  * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
9  * Portions Copyright (c) 1994, Regents of the University of California
10  *
11  *
12  * IDENTIFICATION
13  *        $PostgreSQL: pgsql/src/port/win32env.c,v 1.3 2009/06/11 14:49:15 momjian Exp $
14  *
15  *-------------------------------------------------------------------------
16  */
17
18 #include "c.h"
19
20 int
21 pgwin32_putenv(const char *envval)
22 {
23         char       *envcpy;
24         char       *cp;
25
26         /*
27          * Each version of MSVCRT has its own _putenv() call in the runtime
28          * library.
29          *
30          * If we're in VC 7.0 or later (means != mingw), update in the 6.0
31          * MSVCRT.DLL environment as well, to work with third party libraries
32          * linked against it (such as gnuwin32 libraries).
33          */
34 #if defined(_MSC_VER) && (_MSC_VER >= 1300)
35         typedef int (_cdecl * PUTENVPROC) (const char *);
36         HMODULE         hmodule;
37         static PUTENVPROC putenvFunc = NULL;
38         int                     ret;
39
40         if (putenvFunc == NULL)
41         {
42                 hmodule = GetModuleHandle("msvcrt");
43                 if (hmodule == NULL)
44                         return 1;
45                 putenvFunc = (PUTENVPROC) GetProcAddress(hmodule, "_putenv");
46                 if (putenvFunc == NULL)
47                         return 1;
48         }
49         ret = putenvFunc(envval);
50         if (ret != 0)
51                 return ret;
52 #endif   /* _MSC_VER >= 1300 */
53
54
55         /*
56          * Update the process environment - to make modifications visible to child
57          * processes.
58          *
59          * Need a copy of the string so we can modify it.
60          */
61         envcpy = strdup(envval);
62         cp = strchr(envcpy, '=');
63         if (cp == NULL)
64                 return -1;
65         *cp = '\0';
66         cp++;
67         if (strlen(cp))
68         {
69                 /*
70                  * Only call SetEnvironmentVariable() when we are adding a variable,
71                  * not when removing it. Calling it on both crashes on at least
72                  * certain versions of MingW.
73                  */
74                 if (!SetEnvironmentVariable(envcpy, cp))
75                 {
76                         free(envcpy);
77                         return -1;
78                 }
79         }
80         free(envcpy);
81
82         /* Finally, update our "own" cache */
83         return _putenv(envval);
84 }
85
86 void
87 pgwin32_unsetenv(const char *name)
88 {
89         char       *envbuf;
90
91         envbuf = (char *) malloc(strlen(name) + 2);
92         if (!envbuf)
93                 return;
94
95         sprintf(envbuf, "%s=", name);
96         pgwin32_putenv(envbuf);
97         free(envbuf);
98 }