PostgreSQL Source Code
git master
Loading...
Searching...
No Matches
win32env.c
Go to the documentation of this file.
1
/*-------------------------------------------------------------------------
2
*
3
* win32env.c
4
* putenv(), setenv(), and unsetenv() for win32.
5
*
6
* These functions update both the process environment and caches in
7
* (potentially multiple) C run-time library (CRT) versions.
8
*
9
* Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
10
* Portions Copyright (c) 1994, Regents of the University of California
11
*
12
*
13
* IDENTIFICATION
14
* src/port/win32env.c
15
*
16
*-------------------------------------------------------------------------
17
*/
18
19
#include "
c.h
"
20
21
22
/*
23
* Note that unlike POSIX putenv(), this doesn't use the passed-in string
24
* as permanent storage.
25
*/
26
int
27
pgwin32_putenv
(
const
char
*
envval
)
28
{
29
char
*
envcpy
;
30
char
*
cp
;
31
typedef
int
(
_cdecl
*
PUTENVPROC
) (
const
char
*);
32
static
const
char
*
const
modulenames
[] = {
33
"msvcrt"
,
/* Visual Studio 6.0 / MinGW */
34
"msvcrtd"
,
35
"msvcr70"
,
/* Visual Studio 2002 */
36
"msvcr70d"
,
37
"msvcr71"
,
/* Visual Studio 2003 */
38
"msvcr71d"
,
39
"msvcr80"
,
/* Visual Studio 2005 */
40
"msvcr80d"
,
41
"msvcr90"
,
/* Visual Studio 2008 */
42
"msvcr90d"
,
43
"msvcr100"
,
/* Visual Studio 2010 */
44
"msvcr100d"
,
45
"msvcr110"
,
/* Visual Studio 2012 */
46
"msvcr110d"
,
47
"msvcr120"
,
/* Visual Studio 2013 */
48
"msvcr120d"
,
49
"ucrtbase"
,
/* Visual Studio 2015 and later */
50
"ucrtbased"
,
51
NULL
52
};
53
int
i
;
54
55
/*
56
* Update process environment, making this change visible to child
57
* processes and to CRTs initializing in the future. Do this before the
58
* _putenv() loop, for the benefit of any CRT that initializes during this
59
* pgwin32_putenv() execution, after the loop checks that CRT.
60
*
61
* Need a copy of the string so we can modify it.
62
*/
63
envcpy
=
strdup
(
envval
);
64
if
(!
envcpy
)
65
return
-1;
66
cp
=
strchr
(
envcpy
,
'='
);
67
if
(
cp
==
NULL
)
68
{
69
free
(
envcpy
);
70
return
-1;
71
}
72
*
cp
=
'\0'
;
73
cp
++;
74
if
(*
cp
)
75
{
76
/*
77
* Only call SetEnvironmentVariable() when we are adding a variable,
78
* not when removing it. Calling it on both crashes on at least
79
* certain versions of MinGW.
80
*/
81
if
(!
SetEnvironmentVariable
(
envcpy
,
cp
))
82
{
83
free
(
envcpy
);
84
return
-1;
85
}
86
}
87
free
(
envcpy
);
88
89
/*
90
* Each CRT has its own _putenv() symbol and copy of the environment.
91
* Update the environment in each CRT module currently loaded, so every
92
* third-party library sees this change regardless of the CRT it links
93
* against. Addresses within these modules may become invalid the moment
94
* we call FreeLibrary(), so don't cache them.
95
*/
96
for
(
i
= 0;
modulenames
[
i
];
i
++)
97
{
98
HMODULE
hmodule
=
NULL
;
99
BOOL
res =
GetModuleHandleEx
(0,
modulenames
[
i
], &
hmodule
);
100
101
if
(res != 0 &&
hmodule
!=
NULL
)
102
{
103
PUTENVPROC
putenvFunc
;
104
105
putenvFunc
= (
PUTENVPROC
) (
pg_funcptr_t
)
GetProcAddress
(
hmodule
,
"_putenv"
);
106
if
(
putenvFunc
)
107
putenvFunc
(
envval
);
108
FreeLibrary
(
hmodule
);
109
}
110
}
111
112
/*
113
* Finally, update our "own" cache. This is redundant with the loop
114
* above, except when PostgreSQL itself links to a CRT not listed above.
115
* Ideally, the loop does visit all possible CRTs, making this redundant.
116
*/
117
return
_putenv
(
envval
);
118
}
119
120
int
121
pgwin32_setenv
(
const
char
*
name
,
const
char
*
value
,
int
overwrite
)
122
{
123
int
res;
124
char
*
envstr
;
125
126
/* Error conditions, per POSIX */
127
if
(
name
==
NULL
||
name
[0] ==
'\0'
||
strchr
(
name
,
'='
) !=
NULL
||
128
value
==
NULL
)
129
{
130
errno
=
EINVAL
;
131
return
-1;
132
}
133
134
/* No work if variable exists and we're not to replace it */
135
if
(
overwrite
== 0 &&
getenv
(
name
) !=
NULL
)
136
return
0;
137
138
envstr
= (
char
*)
malloc
(
strlen
(
name
) +
strlen
(
value
) + 2);
139
if
(!
envstr
)
/* not much we can do if no memory */
140
return
-1;
141
142
sprintf
(
envstr
,
"%s=%s"
,
name
,
value
);
143
144
res =
pgwin32_putenv
(
envstr
);
145
free
(
envstr
);
146
return
res;
147
}
148
149
int
150
pgwin32_unsetenv
(
const
char
*
name
)
151
{
152
int
res;
153
char
*
envbuf
;
154
155
/* Error conditions, per POSIX */
156
if
(
name
==
NULL
||
name
[0] ==
'\0'
||
strchr
(
name
,
'='
) !=
NULL
)
157
{
158
errno
=
EINVAL
;
159
return
-1;
160
}
161
162
envbuf
= (
char
*)
malloc
(
strlen
(
name
) + 2);
163
if
(!
envbuf
)
164
return
-1;
165
166
sprintf
(
envbuf
,
"%s="
,
name
);
167
res =
pgwin32_putenv
(
envbuf
);
168
free
(
envbuf
);
169
return
res;
170
}
c.h
pg_funcptr_t
void(* pg_funcptr_t)(void)
Definition
c.h:470
value
static struct @172 value
i
int i
Definition
isn.c:77
sprintf
#define sprintf
Definition
port.h:262
fb
static int fb(int x)
Definition
preproc-init.c:92
free
#define free(a)
Definition
snowball_runtime.h:65
malloc
#define malloc(a)
Definition
snowball_runtime.h:50
overwrite
static void overwrite(PGconn *conn, Oid lobjId, int start, int len)
Definition
testlo.c:108
name
const char * name
Definition
wait_event_funcs.c:28
pgwin32_unsetenv
int pgwin32_unsetenv(const char *name)
Definition
win32env.c:150
pgwin32_putenv
int pgwin32_putenv(const char *envval)
Definition
win32env.c:27
pgwin32_setenv
int pgwin32_setenv(const char *name, const char *value, int overwrite)
Definition
win32env.c:121
src
port
win32env.c
Generated on Thu Jan 29 2026 06:13:18 for PostgreSQL Source Code by
1.9.8