]>
Commit | Line | Data |
---|---|---|
0022d9e3 PO |
1 | /**************************************************************************** |
2 | * * | |
3 | * GNAT COMPILER COMPONENTS * | |
4 | * * | |
5 | * E N V * | |
6 | * * | |
7 | * C Implementation File * | |
8 | * * | |
06c565cc | 9 | * Copyright (C) 2005-2024, Free Software Foundation, Inc. * |
0022d9e3 PO |
10 | * * |
11 | * GNAT is free software; you can redistribute it and/or modify it under * | |
12 | * terms of the GNU General Public License as published by the Free Soft- * | |
748086b7 | 13 | * ware Foundation; either version 3, or (at your option) any later ver- * |
0022d9e3 PO |
14 | * sion. GNAT is distributed in the hope that it will be useful, but WITH- * |
15 | * OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * | |
748086b7 JJ |
16 | * or FITNESS FOR A PARTICULAR PURPOSE. * |
17 | * * | |
18 | * As a special exception under Section 7 of GPL version 3, you are granted * | |
19 | * additional permissions described in the GCC Runtime Library Exception, * | |
20 | * version 3.1, as published by the Free Software Foundation. * | |
21 | * * | |
22 | * You should have received a copy of the GNU General Public License and * | |
23 | * a copy of the GCC Runtime Library Exception along with this program; * | |
24 | * see the files COPYING3 and COPYING.RUNTIME respectively. If not, see * | |
25 | * <http://www.gnu.org/licenses/>. * | |
0022d9e3 PO |
26 | * * |
27 | * GNAT was originally developed by the GNAT team at New York University. * | |
28 | * Extensive contributions were provided by Ada Core Technologies Inc. * | |
29 | * * | |
30 | ****************************************************************************/ | |
31 | ||
32 | #ifdef IN_RTS | |
a6fc663e AC |
33 | # include "runtime.h" |
34 | # include <stdio.h> | |
35 | # include <stdlib.h> | |
36 | # include <string.h> | |
1de83011 | 37 | |
1de83011 TG |
38 | /* We don't have libiberty, so use malloc. */ |
39 | # define xmalloc(S) malloc (S) | |
40 | #else /* IN_RTS */ | |
41 | # include "config.h" | |
42 | # include "system.h" | |
43 | #endif /* IN_RTS */ | |
0022d9e3 | 44 | |
0022d9e3 PO |
45 | #if defined (__MINGW32__) |
46 | #include <stdlib.h> | |
47 | #endif | |
48 | ||
39b76371 JL |
49 | #if defined (__APPLE__) \ |
50 | && !(defined (__arm__) \ | |
51 | || defined (__arm64__) \ | |
52 | || defined (__IOS_SIMULATOR__)) | |
6a989c79 | 53 | /* On Darwin, _NSGetEnviron must be used for shared libraries; but it is not |
39b76371 | 54 | available on iOS (on device or on simulator). */ |
6a989c79 AC |
55 | #include <crt_externs.h> |
56 | #endif | |
57 | ||
97ed5872 | 58 | #if defined (__vxworks) |
32e0627f DR |
59 | #include <vxWorks.h> |
60 | #include <version.h> | |
61 | ||
97ed5872 AC |
62 | #if defined (__RTP__) |
63 | /* On VxWorks 6 Real-Time process mode, environ is defined in unistd.h. */ | |
64 | #include <unistd.h> | |
65 | #elif defined (VTHREADS) | |
66 | /* VTHREADS mode applies to both VxWorks 653 and VxWorks MILS. The | |
67 | inclusion of vThreadsData.h is necessary to workaround a bug with | |
73242473 | 68 | envLib.h on VxWorks MILS and VxWorks 653. */ |
97ed5872 AC |
69 | #include <vThreadsData.h> |
70 | #include <envLib.h> | |
512fe5e0 PB |
71 | #else |
72 | /* Kernel mode */ | |
97ed5872 | 73 | #include <envLib.h> |
97ed5872 | 74 | #endif |
0022d9e3 PO |
75 | #endif |
76 | ||
8afd02aa EB |
77 | #ifdef __cplusplus |
78 | extern "C" { | |
79 | #endif | |
80 | ||
84df40f7 AC |
81 | #ifdef VMS |
82 | #include <vms/descrip.h> | |
83 | #endif | |
84 | ||
0022d9e3 PO |
85 | #include "env.h" |
86 | ||
87 | void | |
88 | __gnat_getenv (char *name, int *len, char **value) | |
89 | { | |
90 | *value = getenv (name); | |
91 | if (!*value) | |
92 | *len = 0; | |
93 | else | |
94 | *len = strlen (*value); | |
95 | ||
96 | return; | |
97 | } | |
98 | ||
0022d9e3 PO |
99 | void |
100 | __gnat_setenv (char *name, char *value) | |
101 | { | |
603b57c7 PB |
102 | #if (defined (__vxworks) && (defined (__RTP__) || _WRS_VXWORKS_MAJOR >= 7)) \ |
103 | || defined (__APPLE__) | |
0022d9e3 PO |
104 | setenv (name, value, 1); |
105 | ||
106 | #else | |
fd7927cd | 107 | size_t size = strlen (name) + strlen (value) + 2; |
0022d9e3 PO |
108 | char *expression; |
109 | ||
110 | expression = (char *) xmalloc (size * sizeof (char)); | |
111 | ||
112 | sprintf (expression, "%s=%s", name, value); | |
113 | putenv (expression); | |
603b57c7 PB |
114 | #if defined (__MINGW32__) || defined (__vxworks) |
115 | /* putenv for Windows and VxWorks 6 kernel modules makes a copy of the | |
116 | expression string, so we need to free it after the call to putenv. */ | |
0022d9e3 PO |
117 | free (expression); |
118 | #endif | |
119 | #endif | |
120 | } | |
121 | ||
122 | char ** | |
123 | __gnat_environ (void) | |
124 | { | |
a6fc663e | 125 | #if defined (__MINGW32__) |
0022d9e3 | 126 | return _environ; |
329be64b | 127 | #elif defined (__sun__) |
0022d9e3 PO |
128 | extern char **_environ; |
129 | return _environ; | |
39b76371 JL |
130 | #elif defined (__APPLE__) \ |
131 | && !(defined (__arm__) \ | |
132 | || defined (__arm64__) \ | |
133 | || defined (__IOS_SIMULATOR__)) | |
aebab21a | 134 | return *_NSGetEnviron (); |
97ed5872 | 135 | #elif ! (defined (__vxworks)) |
0022d9e3 | 136 | extern char **environ; |
97ed5872 AC |
137 | return environ; |
138 | #else | |
512fe5e0 | 139 | #if defined (__RTP__) || defined (VTHREADS) |
32e0627f | 140 | return environ; |
512fe5e0 | 141 | #else |
603b57c7 PB |
142 | /* For VxWorks kernel modules use envGet to get the task's environment |
143 | (either the task's private environment if it has one or the global | |
144 | environment otherwise). taskId parameter of 0 refers to the current | |
145 | task (the VxWorks documentation says to use NULL but the compiler | |
146 | complains that taskId is an int rather than a pointer. Internally, | |
147 | VxWorks uses 0 as well). */ | |
148 | return envGet (0); | |
32e0627f | 149 | #endif |
0022d9e3 PO |
150 | #endif |
151 | } | |
152 | ||
a1d3851b AC |
153 | void __gnat_unsetenv (char *name) |
154 | { | |
a6fc663e | 155 | #if defined (__hpux__) || defined (__sun__) \ |
603b57c7 PB |
156 | || (defined (__vxworks) && ! defined (__RTP__) \ |
157 | && _WRS_VXWORKS_MAJOR <= 6) \ | |
bfc8aa81 | 158 | || defined (_AIX) || defined (__Lynx__) |
0022d9e3 | 159 | |
b24513a1 | 160 | /* On Solaris and HP-UX there is no function to clear an environment |
0022d9e3 PO |
161 | variable. So we look for the variable in the environ table and delete it |
162 | by setting the entry to NULL. This can clearly cause some memory leaks | |
163 | but free cannot be used on this context as not all strings in the environ | |
164 | have been allocated using malloc. To avoid this memory leak another | |
165 | method can be used. It consists in forcing the reallocation of all the | |
166 | strings in the environ table using malloc on the first call on the | |
ce2e12c2 | 167 | functions related to environment variable management. The disadvantage |
0022d9e3 PO |
168 | is that if a program makes a direct call to getenv the return string |
169 | may be deallocated at some point. */ | |
170 | /* Note that on AIX, unsetenv is not supported on 5.1 but it is on 5.3. | |
171 | As we are still supporting AIX 5.1 we cannot use unsetenv */ | |
172 | char **env = __gnat_environ (); | |
173 | int index = 0; | |
fd7927cd | 174 | size_t size = strlen (name); |
0022d9e3 PO |
175 | |
176 | while (env[index] != NULL) { | |
177 | if (strlen (env[index]) > size) { | |
178 | if (strstr (env[index], name) == env[index] && | |
179 | env[index][size] == '=') { | |
603b57c7 | 180 | #if defined (__vxworks) |
0022d9e3 PO |
181 | /* on Vxworks we are sure that the string has been allocated using |
182 | malloc */ | |
183 | free (env[index]); | |
184 | #endif | |
185 | while (env[index] != NULL) { | |
186 | env[index]=env[index + 1]; | |
187 | index++; | |
188 | } | |
189 | } else | |
190 | index++; | |
191 | } else | |
192 | index++; | |
193 | } | |
194 | #elif defined (__MINGW32__) | |
195 | /* On Windows platform putenv ("key=") is equivalent to unsetenv (a | |
196 | subsequent call to getenv ("key") will return NULL and not the "\0" | |
197 | string */ | |
fd7927cd | 198 | size_t size = strlen (name) + 2; |
0022d9e3 PO |
199 | char *expression; |
200 | expression = (char *) xmalloc (size * sizeof (char)); | |
201 | ||
202 | sprintf (expression, "%s=", name); | |
203 | putenv (expression); | |
204 | free (expression); | |
205 | #else | |
206 | unsetenv (name); | |
207 | #endif | |
208 | } | |
209 | ||
a1d3851b AC |
210 | void __gnat_clearenv (void) |
211 | { | |
a6fc663e | 212 | #if defined (__sun__) \ |
603b57c7 PB |
213 | || (defined (__vxworks) && !defined (__RTP__) && _WRS_VXWORKS_MAJOR <= 6) \ |
214 | || defined (__Lynx__) \ | |
a1d3851b | 215 | || defined (__PikeOS__) |
603b57c7 | 216 | /* On Solaris, VxWorks kernel pre 7, and Lynx there is no system |
0022d9e3 PO |
217 | call to unset a variable or to clear the environment so set all |
218 | the entries in the environ table to NULL (see comment in | |
219 | __gnat_unsetenv for more explanation). */ | |
220 | char **env = __gnat_environ (); | |
221 | int index = 0; | |
222 | ||
223 | while (env[index] != NULL) { | |
224 | env[index]=NULL; | |
225 | index++; | |
226 | } | |
227 | #elif defined (__MINGW32__) || defined (__FreeBSD__) || defined (__APPLE__) \ | |
603b57c7 PB |
228 | || (defined (__vxworks) && defined (__RTP__) || _WRS_VXWORKS_MAJOR >= 7) \ |
229 | || defined (__CYGWIN__) \ | |
90af5990 | 230 | || defined (__NetBSD__) || defined (__OpenBSD__) || defined (__rtems__) \ |
4f100fd7 | 231 | || defined (__DragonFly__) || defined (__DJGPP__) |
0022d9e3 PO |
232 | /* On Windows, FreeBSD and MacOS there is no function to clean all the |
233 | environment but there is a "clean" way to unset a variable. So go | |
234 | through the environ table and call __gnat_unsetenv on all entries */ | |
235 | char **env = __gnat_environ (); | |
fd7927cd | 236 | size_t size; |
0022d9e3 PO |
237 | |
238 | while (env[0] != NULL) { | |
239 | size = 0; | |
240 | while (env[0][size] != '=') | |
241 | size++; | |
242 | /* create a string that contains "name" */ | |
243 | size++; | |
244 | { | |
78efd712 AC |
245 | char *expression; |
246 | expression = (char *) xmalloc (size * sizeof (char)); | |
0022d9e3 PO |
247 | strncpy (expression, env[0], size); |
248 | expression[size - 1] = 0; | |
249 | __gnat_unsetenv (expression); | |
78efd712 | 250 | free (expression); |
0022d9e3 PO |
251 | } |
252 | } | |
253 | #else | |
254 | clearenv (); | |
255 | #endif | |
256 | } | |
9e9bd455 LG |
257 | |
258 | #ifdef __cplusplus | |
259 | } | |
260 | #endif |