1010 *
1111 *
1212 * IDENTIFICATION
13- * $PostgreSQL: pgsql/src/port/win32env.c,v 1.5 2009/12/27 16:11:28 mha Exp $
13+ * $PostgreSQL: pgsql/src/port/win32env.c,v 1.6 2010/01/01 14:57:16 mha Exp $
1414 *
1515 *-------------------------------------------------------------------------
1616 */
@@ -27,34 +27,72 @@ pgwin32_putenv(const char *envval)
2727 * Each version of MSVCRT has its own _putenv() call in the runtime
2828 * library.
2929 *
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).
30+ * mingw always uses MSVCRT.DLL, but if we are in a Visual C++ environment,
31+ * attempt to update the environment in all MSVCRT modules that are
32+ * currently loaded, to work properly with any third party libraries
33+ * linked against a different MSVCRT but still relying on environment
34+ * variables.
35+ *
36+ * Also separately update the system environment that gets inherited by
37+ * subprocesses.
3338 */
34- #if defined( _MSC_VER ) && ( _MSC_VER >= 1300 )
39+ #ifdef _MSC_VER
3540 typedef int (_cdecl * PUTENVPROC ) (const char * );
36- HMODULE hmodule ;
37- static PUTENVPROC putenvFunc = NULL ;
41+ static struct {
42+ char * modulename ;
43+ HMODULE hmodule ;
44+ PUTENVPROC putenvFunc ;
45+ } rtmodules [] = {
46+ { "msvcrt" , 0 , NULL }, /* Visual Studio 6.0 / mingw */
47+ { "msvcr70" , 0 , NULL }, /* Visual Studio 2002 */
48+ { "msvcr71" , 0 , NULL }, /* Visual Studio 2003 */
49+ { "msvcr80" , 0 , NULL }, /* Visual Studio 2005 */
50+ { "msvcr90" , 0 , NULL }, /* Visual Studio 2008 */
51+ { NULL , 0 , NULL }
52+ };
53+ int i ;
3854
39- if ( putenvFunc == NULL )
55+ for ( i = 0 ; rtmodules [ i ]. modulename ; i ++ )
4056 {
41- hmodule = GetModuleHandle ("msvcrt" );
42- if (hmodule != NULL )
57+ if (rtmodules [i ].putenvFunc == NULL )
4358 {
44- /*
45- * If the module is found, attempt to find the function. If not, that just
46- * means we're not linked with msvcrt, so fall through and make our other
47- * modifications anyway.
48- * Ignore any errors and update whatever we can, since callers don't
49- * check the return value anyway.
50- */
51- putenvFunc = (PUTENVPROC ) GetProcAddress (hmodule , "_putenv" );
52- if (putenvFunc != NULL )
53- putenvFunc (envval );
59+ if (rtmodules [i ].hmodule == 0 )
60+ {
61+ /* Not attempted before, so try to find this DLL */
62+ rtmodules [i ].hmodule = GetModuleHandle (rtmodules [i ].modulename );
63+ if (rtmodules [i ].hmodule == NULL )
64+ {
65+ /*
66+ * Set to INVALID_HANDLE_VALUE so we know we have tried this one
67+ * before, and won't try again.
68+ */
69+ rtmodules [i ].hmodule = INVALID_HANDLE_VALUE ;
70+ continue ;
71+ }
72+ else
73+ {
74+ rtmodules [i ].putenvFunc = (PUTENVPROC ) GetProcAddress (rtmodules [i ].hmodule , "_putenv" );
75+ if (rtmodules [i ].putenvFunc == NULL )
76+ {
77+ CloseHandle (rtmodules [i ].hmodule );
78+ rtmodules [i ].hmodule = INVALID_HANDLE_VALUE ;
79+ continue ;
80+ }
81+ }
82+ }
83+ else
84+ {
85+ /*
86+ * Module loaded, but we did not find the function last time. We're
87+ * not going to find it this time either...
88+ */
89+ continue ;
90+ }
5491 }
92+ /* At this point, putenvFunc is set or we have exited the loop */
93+ rtmodules [i ].putenvFunc (envval );
5594 }
56- #endif /* _MSC_VER >= 1300 */
57-
95+ #endif /* _MSC_VER */
5896
5997 /*
6098 * Update the process environment - to make modifications visible to child
0 commit comments