annotate gcc/ada/env.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /****************************************************************************
kono
parents:
diff changeset
2 * *
kono
parents:
diff changeset
3 * GNAT COMPILER COMPONENTS *
kono
parents:
diff changeset
4 * *
kono
parents:
diff changeset
5 * E N V *
kono
parents:
diff changeset
6 * *
kono
parents:
diff changeset
7 * C Implementation File *
kono
parents:
diff changeset
8 * *
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
9 * Copyright (C) 2005-2018, Free Software Foundation, Inc. *
111
kono
parents:
diff changeset
10 * *
kono
parents:
diff changeset
11 * GNAT is free software; you can redistribute it and/or modify it under *
kono
parents:
diff changeset
12 * terms of the GNU General Public License as published by the Free Soft- *
kono
parents:
diff changeset
13 * ware Foundation; either version 3, or (at your option) any later ver- *
kono
parents:
diff changeset
14 * sion. GNAT is distributed in the hope that it will be useful, but WITH- *
kono
parents:
diff changeset
15 * OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
kono
parents:
diff changeset
16 * or FITNESS FOR A PARTICULAR PURPOSE. *
kono
parents:
diff changeset
17 * *
kono
parents:
diff changeset
18 * As a special exception under Section 7 of GPL version 3, you are granted *
kono
parents:
diff changeset
19 * additional permissions described in the GCC Runtime Library Exception, *
kono
parents:
diff changeset
20 * version 3.1, as published by the Free Software Foundation. *
kono
parents:
diff changeset
21 * *
kono
parents:
diff changeset
22 * You should have received a copy of the GNU General Public License and *
kono
parents:
diff changeset
23 * a copy of the GCC Runtime Library Exception along with this program; *
kono
parents:
diff changeset
24 * see the files COPYING3 and COPYING.RUNTIME respectively. If not, see *
kono
parents:
diff changeset
25 * <http://www.gnu.org/licenses/>. *
kono
parents:
diff changeset
26 * *
kono
parents:
diff changeset
27 * GNAT was originally developed by the GNAT team at New York University. *
kono
parents:
diff changeset
28 * Extensive contributions were provided by Ada Core Technologies Inc. *
kono
parents:
diff changeset
29 * *
kono
parents:
diff changeset
30 ****************************************************************************/
kono
parents:
diff changeset
31
kono
parents:
diff changeset
32 #ifdef IN_RTS
kono
parents:
diff changeset
33 # include "tconfig.h"
kono
parents:
diff changeset
34 # include "tsystem.h"
kono
parents:
diff changeset
35
kono
parents:
diff changeset
36 # include <sys/stat.h>
kono
parents:
diff changeset
37 # include <fcntl.h>
kono
parents:
diff changeset
38 # include <time.h>
kono
parents:
diff changeset
39 # ifdef VMS
kono
parents:
diff changeset
40 # include <unixio.h>
kono
parents:
diff changeset
41 # endif
kono
parents:
diff changeset
42 /* We don't have libiberty, so use malloc. */
kono
parents:
diff changeset
43 # define xmalloc(S) malloc (S)
kono
parents:
diff changeset
44 #else /* IN_RTS */
kono
parents:
diff changeset
45 # include "config.h"
kono
parents:
diff changeset
46 # include "system.h"
kono
parents:
diff changeset
47 #endif /* IN_RTS */
kono
parents:
diff changeset
48
kono
parents:
diff changeset
49 #if defined (__MINGW32__)
kono
parents:
diff changeset
50 #include <stdlib.h>
kono
parents:
diff changeset
51 #endif
kono
parents:
diff changeset
52
kono
parents:
diff changeset
53 #if defined (__APPLE__) && !(defined (__arm__) || defined (__arm64__))
kono
parents:
diff changeset
54 /* On Darwin, _NSGetEnviron must be used for shared libraries; but it is not
kono
parents:
diff changeset
55 available on iOS. */
kono
parents:
diff changeset
56 #include <crt_externs.h>
kono
parents:
diff changeset
57 #endif
kono
parents:
diff changeset
58
kono
parents:
diff changeset
59 #if defined (__vxworks)
kono
parents:
diff changeset
60 #if defined (__RTP__)
kono
parents:
diff changeset
61 /* On VxWorks 6 Real-Time process mode, environ is defined in unistd.h. */
kono
parents:
diff changeset
62 #include <unistd.h>
kono
parents:
diff changeset
63 #elif defined (VTHREADS)
kono
parents:
diff changeset
64 /* VTHREADS mode applies to both VxWorks 653 and VxWorks MILS. The
kono
parents:
diff changeset
65 inclusion of vThreadsData.h is necessary to workaround a bug with
kono
parents:
diff changeset
66 envLib.h on VxWorks MILS and VxWorks 653. */
kono
parents:
diff changeset
67 #include <vThreadsData.h>
kono
parents:
diff changeset
68 #include <envLib.h>
kono
parents:
diff changeset
69 #else
kono
parents:
diff changeset
70 /* This should work for kernel mode on both VxWorks 5 and VxWorks 6. */
kono
parents:
diff changeset
71 #include <envLib.h>
kono
parents:
diff changeset
72
kono
parents:
diff changeset
73 /* In that mode environ is a macro which reference the following symbol.
kono
parents:
diff changeset
74 As the symbol is not defined in any VxWorks include files we declare
kono
parents:
diff changeset
75 it as extern. */
kono
parents:
diff changeset
76 extern char** ppGlobalEnviron;
kono
parents:
diff changeset
77 #endif
kono
parents:
diff changeset
78 #endif
kono
parents:
diff changeset
79
kono
parents:
diff changeset
80 #ifdef __cplusplus
kono
parents:
diff changeset
81 extern "C" {
kono
parents:
diff changeset
82 #endif
kono
parents:
diff changeset
83
kono
parents:
diff changeset
84 #ifdef VMS
kono
parents:
diff changeset
85 #include <vms/descrip.h>
kono
parents:
diff changeset
86 #endif
kono
parents:
diff changeset
87
kono
parents:
diff changeset
88 #include "env.h"
kono
parents:
diff changeset
89
kono
parents:
diff changeset
90 void
kono
parents:
diff changeset
91 __gnat_getenv (char *name, int *len, char **value)
kono
parents:
diff changeset
92 {
kono
parents:
diff changeset
93 *value = getenv (name);
kono
parents:
diff changeset
94 if (!*value)
kono
parents:
diff changeset
95 *len = 0;
kono
parents:
diff changeset
96 else
kono
parents:
diff changeset
97 *len = strlen (*value);
kono
parents:
diff changeset
98
kono
parents:
diff changeset
99 return;
kono
parents:
diff changeset
100 }
kono
parents:
diff changeset
101
kono
parents:
diff changeset
102 /* VMS specific declarations for set_env_value. */
kono
parents:
diff changeset
103
kono
parents:
diff changeset
104 #ifdef VMS
kono
parents:
diff changeset
105
kono
parents:
diff changeset
106 typedef struct _ile3
kono
parents:
diff changeset
107 {
kono
parents:
diff changeset
108 unsigned short len, code;
kono
parents:
diff changeset
109 __char_ptr32 adr;
kono
parents:
diff changeset
110 __char_ptr32 retlen_adr;
kono
parents:
diff changeset
111 } ile_s;
kono
parents:
diff changeset
112
kono
parents:
diff changeset
113 #endif
kono
parents:
diff changeset
114
kono
parents:
diff changeset
115 void
kono
parents:
diff changeset
116 __gnat_setenv (char *name, char *value)
kono
parents:
diff changeset
117 {
kono
parents:
diff changeset
118 #if defined (VMS)
kono
parents:
diff changeset
119 struct dsc$descriptor_s name_desc;
kono
parents:
diff changeset
120 $DESCRIPTOR (table_desc, "LNM$PROCESS");
kono
parents:
diff changeset
121 char *host_pathspec = value;
kono
parents:
diff changeset
122 char *copy_pathspec;
kono
parents:
diff changeset
123 int num_dirs_in_pathspec = 1;
kono
parents:
diff changeset
124 char *ptr;
kono
parents:
diff changeset
125 long status;
kono
parents:
diff changeset
126
kono
parents:
diff changeset
127 name_desc.dsc$w_length = strlen (name);
kono
parents:
diff changeset
128 name_desc.dsc$b_dtype = DSC$K_DTYPE_T;
kono
parents:
diff changeset
129 name_desc.dsc$b_class = DSC$K_CLASS_S;
kono
parents:
diff changeset
130 name_desc.dsc$a_pointer = name; /* ??? Danger, not 64bit safe. */
kono
parents:
diff changeset
131
kono
parents:
diff changeset
132 if (*host_pathspec == 0)
kono
parents:
diff changeset
133 /* deassign */
kono
parents:
diff changeset
134 {
kono
parents:
diff changeset
135 status = LIB$DELETE_LOGICAL (&name_desc, &table_desc);
kono
parents:
diff changeset
136 /* no need to check status; if the logical name is not
kono
parents:
diff changeset
137 defined, that's fine. */
kono
parents:
diff changeset
138 return;
kono
parents:
diff changeset
139 }
kono
parents:
diff changeset
140
kono
parents:
diff changeset
141 ptr = host_pathspec;
kono
parents:
diff changeset
142 while (*ptr++)
kono
parents:
diff changeset
143 if (*ptr == ',')
kono
parents:
diff changeset
144 num_dirs_in_pathspec++;
kono
parents:
diff changeset
145
kono
parents:
diff changeset
146 {
kono
parents:
diff changeset
147 int i, status;
kono
parents:
diff changeset
148 /* Alloca is guaranteed to be 32bit. */
kono
parents:
diff changeset
149 ile_s *ile_array = alloca (sizeof (ile_s) * (num_dirs_in_pathspec + 1));
kono
parents:
diff changeset
150 char *copy_pathspec = alloca (strlen (host_pathspec) + 1);
kono
parents:
diff changeset
151 char *curr, *next;
kono
parents:
diff changeset
152
kono
parents:
diff changeset
153 strcpy (copy_pathspec, host_pathspec);
kono
parents:
diff changeset
154 curr = copy_pathspec;
kono
parents:
diff changeset
155 for (i = 0; i < num_dirs_in_pathspec; i++)
kono
parents:
diff changeset
156 {
kono
parents:
diff changeset
157 next = strchr (curr, ',');
kono
parents:
diff changeset
158 if (next == 0)
kono
parents:
diff changeset
159 next = strchr (curr, 0);
kono
parents:
diff changeset
160
kono
parents:
diff changeset
161 *next = 0;
kono
parents:
diff changeset
162 ile_array[i].len = strlen (curr);
kono
parents:
diff changeset
163
kono
parents:
diff changeset
164 /* Code 2 from lnmdef.h means it's a string. */
kono
parents:
diff changeset
165 ile_array[i].code = 2;
kono
parents:
diff changeset
166 ile_array[i].adr = curr;
kono
parents:
diff changeset
167
kono
parents:
diff changeset
168 /* retlen_adr is ignored. */
kono
parents:
diff changeset
169 ile_array[i].retlen_adr = 0;
kono
parents:
diff changeset
170 curr = next + 1;
kono
parents:
diff changeset
171 }
kono
parents:
diff changeset
172
kono
parents:
diff changeset
173 /* Terminating item must be zero. */
kono
parents:
diff changeset
174 ile_array[i].len = 0;
kono
parents:
diff changeset
175 ile_array[i].code = 0;
kono
parents:
diff changeset
176 ile_array[i].adr = 0;
kono
parents:
diff changeset
177 ile_array[i].retlen_adr = 0;
kono
parents:
diff changeset
178
kono
parents:
diff changeset
179 status = LIB$SET_LOGICAL (&name_desc, 0, &table_desc, 0, ile_array);
kono
parents:
diff changeset
180 if ((status & 1) != 1)
kono
parents:
diff changeset
181 LIB$SIGNAL (status);
kono
parents:
diff changeset
182 }
kono
parents:
diff changeset
183
kono
parents:
diff changeset
184 #elif (defined (__vxworks) && defined (__RTP__)) || defined (__APPLE__)
kono
parents:
diff changeset
185 setenv (name, value, 1);
kono
parents:
diff changeset
186
kono
parents:
diff changeset
187 #else
kono
parents:
diff changeset
188 size_t size = strlen (name) + strlen (value) + 2;
kono
parents:
diff changeset
189 char *expression;
kono
parents:
diff changeset
190
kono
parents:
diff changeset
191 expression = (char *) xmalloc (size * sizeof (char));
kono
parents:
diff changeset
192
kono
parents:
diff changeset
193 sprintf (expression, "%s=%s", name, value);
kono
parents:
diff changeset
194 putenv (expression);
kono
parents:
diff changeset
195 #if defined (__MINGW32__) || (defined (__vxworks) && ! defined (__RTP__))
kono
parents:
diff changeset
196 /* On some systems like MacOS X and Windows, putenv is making a copy of the
kono
parents:
diff changeset
197 expression string so we can free it after the call to putenv */
kono
parents:
diff changeset
198 free (expression);
kono
parents:
diff changeset
199 #endif
kono
parents:
diff changeset
200 #endif
kono
parents:
diff changeset
201 }
kono
parents:
diff changeset
202
kono
parents:
diff changeset
203 char **
kono
parents:
diff changeset
204 __gnat_environ (void)
kono
parents:
diff changeset
205 {
kono
parents:
diff changeset
206 #if defined (VMS) || defined (RTX)
kono
parents:
diff changeset
207 /* Not implemented */
kono
parents:
diff changeset
208 return NULL;
kono
parents:
diff changeset
209 #elif defined (__MINGW32__)
kono
parents:
diff changeset
210 return _environ;
kono
parents:
diff changeset
211 #elif defined (__sun__)
kono
parents:
diff changeset
212 extern char **_environ;
kono
parents:
diff changeset
213 return _environ;
kono
parents:
diff changeset
214 #elif defined (__APPLE__) && !(defined (__arm__) || defined (__arm64__))
kono
parents:
diff changeset
215 return *_NSGetEnviron ();
kono
parents:
diff changeset
216 #elif ! (defined (__vxworks))
kono
parents:
diff changeset
217 extern char **environ;
kono
parents:
diff changeset
218 return environ;
kono
parents:
diff changeset
219 #else
kono
parents:
diff changeset
220 return environ;
kono
parents:
diff changeset
221 #endif
kono
parents:
diff changeset
222 }
kono
parents:
diff changeset
223
kono
parents:
diff changeset
224 void __gnat_unsetenv (char *name)
kono
parents:
diff changeset
225 {
kono
parents:
diff changeset
226 #if defined (VMS)
kono
parents:
diff changeset
227 /* Not implemented */
kono
parents:
diff changeset
228 return;
kono
parents:
diff changeset
229 #elif defined (__hpux__) || defined (__sun__) \
kono
parents:
diff changeset
230 || (defined (__vxworks) && ! defined (__RTP__)) \
kono
parents:
diff changeset
231 || defined (_AIX) || defined (__Lynx__)
kono
parents:
diff changeset
232
kono
parents:
diff changeset
233 /* On Solaris and HP-UX there is no function to clear an environment
kono
parents:
diff changeset
234 variable. So we look for the variable in the environ table and delete it
kono
parents:
diff changeset
235 by setting the entry to NULL. This can clearly cause some memory leaks
kono
parents:
diff changeset
236 but free cannot be used on this context as not all strings in the environ
kono
parents:
diff changeset
237 have been allocated using malloc. To avoid this memory leak another
kono
parents:
diff changeset
238 method can be used. It consists in forcing the reallocation of all the
kono
parents:
diff changeset
239 strings in the environ table using malloc on the first call on the
kono
parents:
diff changeset
240 functions related to environment variable management. The disadvantage
kono
parents:
diff changeset
241 is that if a program makes a direct call to getenv the return string
kono
parents:
diff changeset
242 may be deallocated at some point. */
kono
parents:
diff changeset
243 /* Note that on AIX, unsetenv is not supported on 5.1 but it is on 5.3.
kono
parents:
diff changeset
244 As we are still supporting AIX 5.1 we cannot use unsetenv */
kono
parents:
diff changeset
245 char **env = __gnat_environ ();
kono
parents:
diff changeset
246 int index = 0;
kono
parents:
diff changeset
247 size_t size = strlen (name);
kono
parents:
diff changeset
248
kono
parents:
diff changeset
249 while (env[index] != NULL) {
kono
parents:
diff changeset
250 if (strlen (env[index]) > size) {
kono
parents:
diff changeset
251 if (strstr (env[index], name) == env[index] &&
kono
parents:
diff changeset
252 env[index][size] == '=') {
kono
parents:
diff changeset
253 #if defined (__vxworks) && ! defined (__RTP__)
kono
parents:
diff changeset
254 /* on Vxworks we are sure that the string has been allocated using
kono
parents:
diff changeset
255 malloc */
kono
parents:
diff changeset
256 free (env[index]);
kono
parents:
diff changeset
257 #endif
kono
parents:
diff changeset
258 while (env[index] != NULL) {
kono
parents:
diff changeset
259 env[index]=env[index + 1];
kono
parents:
diff changeset
260 index++;
kono
parents:
diff changeset
261 }
kono
parents:
diff changeset
262 } else
kono
parents:
diff changeset
263 index++;
kono
parents:
diff changeset
264 } else
kono
parents:
diff changeset
265 index++;
kono
parents:
diff changeset
266 }
kono
parents:
diff changeset
267 #elif defined (__MINGW32__)
kono
parents:
diff changeset
268 /* On Windows platform putenv ("key=") is equivalent to unsetenv (a
kono
parents:
diff changeset
269 subsequent call to getenv ("key") will return NULL and not the "\0"
kono
parents:
diff changeset
270 string */
kono
parents:
diff changeset
271 size_t size = strlen (name) + 2;
kono
parents:
diff changeset
272 char *expression;
kono
parents:
diff changeset
273 expression = (char *) xmalloc (size * sizeof (char));
kono
parents:
diff changeset
274
kono
parents:
diff changeset
275 sprintf (expression, "%s=", name);
kono
parents:
diff changeset
276 putenv (expression);
kono
parents:
diff changeset
277 free (expression);
kono
parents:
diff changeset
278 #else
kono
parents:
diff changeset
279 unsetenv (name);
kono
parents:
diff changeset
280 #endif
kono
parents:
diff changeset
281 }
kono
parents:
diff changeset
282
kono
parents:
diff changeset
283 void __gnat_clearenv (void)
kono
parents:
diff changeset
284 {
kono
parents:
diff changeset
285 #if defined (VMS)
kono
parents:
diff changeset
286 /* not implemented */
kono
parents:
diff changeset
287 return;
kono
parents:
diff changeset
288 #elif defined (__sun__) \
kono
parents:
diff changeset
289 || (defined (__vxworks) && ! defined (__RTP__)) || defined (__Lynx__) \
kono
parents:
diff changeset
290 || defined (__PikeOS__)
kono
parents:
diff changeset
291 /* On Solaris, VxWorks (not RTPs), and Lynx there is no system
kono
parents:
diff changeset
292 call to unset a variable or to clear the environment so set all
kono
parents:
diff changeset
293 the entries in the environ table to NULL (see comment in
kono
parents:
diff changeset
294 __gnat_unsetenv for more explanation). */
kono
parents:
diff changeset
295 char **env = __gnat_environ ();
kono
parents:
diff changeset
296 int index = 0;
kono
parents:
diff changeset
297
kono
parents:
diff changeset
298 while (env[index] != NULL) {
kono
parents:
diff changeset
299 env[index]=NULL;
kono
parents:
diff changeset
300 index++;
kono
parents:
diff changeset
301 }
kono
parents:
diff changeset
302 #elif defined (__MINGW32__) || defined (__FreeBSD__) || defined (__APPLE__) \
kono
parents:
diff changeset
303 || (defined (__vxworks) && defined (__RTP__)) || defined (__CYGWIN__) \
kono
parents:
diff changeset
304 || defined (__NetBSD__) || defined (__OpenBSD__) || defined (__rtems__) \
kono
parents:
diff changeset
305 || defined (__DragonFly__) || defined (__DJGPP__)
kono
parents:
diff changeset
306 /* On Windows, FreeBSD and MacOS there is no function to clean all the
kono
parents:
diff changeset
307 environment but there is a "clean" way to unset a variable. So go
kono
parents:
diff changeset
308 through the environ table and call __gnat_unsetenv on all entries */
kono
parents:
diff changeset
309 char **env = __gnat_environ ();
kono
parents:
diff changeset
310 size_t size;
kono
parents:
diff changeset
311
kono
parents:
diff changeset
312 while (env[0] != NULL) {
kono
parents:
diff changeset
313 size = 0;
kono
parents:
diff changeset
314 while (env[0][size] != '=')
kono
parents:
diff changeset
315 size++;
kono
parents:
diff changeset
316 /* create a string that contains "name" */
kono
parents:
diff changeset
317 size++;
kono
parents:
diff changeset
318 {
kono
parents:
diff changeset
319 char *expression;
kono
parents:
diff changeset
320 expression = (char *) xmalloc (size * sizeof (char));
kono
parents:
diff changeset
321 strncpy (expression, env[0], size);
kono
parents:
diff changeset
322 expression[size - 1] = 0;
kono
parents:
diff changeset
323 __gnat_unsetenv (expression);
kono
parents:
diff changeset
324 free (expression);
kono
parents:
diff changeset
325 }
kono
parents:
diff changeset
326 }
kono
parents:
diff changeset
327 #else
kono
parents:
diff changeset
328 clearenv ();
kono
parents:
diff changeset
329 #endif
kono
parents:
diff changeset
330 }
kono
parents:
diff changeset
331
kono
parents:
diff changeset
332 #ifdef __cplusplus
kono
parents:
diff changeset
333 }
kono
parents:
diff changeset
334 #endif