Mercurial > hg > octave-kai > gnulib-hg
annotate lib/setenv.c @ 17160:72f4bab621be
fts: introduce FTS_VERBATIM
This gives clients the option to disable stripping of trailing slashes
from input path names during fts_open initialization.
The recent change v0.0-7611-g3a9002d that made fts_open strip trailing
slashes from input path names had a negative impact on findutils that
relies on the old fts_open behavior to implement POSIX requirement that
each path operand of the find utility shall be evaluated unaltered as it
was provided, including all trailing slash characters.
* lib/fts_.h (FTS_VERBATIM): New bit flag.
(FTS_OPTIONMASK, FTS_NAMEONLY, FTS_STOP): Adjust.
* lib/fts.c (fts_open): Honor it.
author | Dmitry V. Levin <ldv@altlinux.org> |
---|---|
date | Sun, 18 Nov 2012 04:40:18 +0400 |
parents | 18a38c9615f0 |
children | e542fd46ad6f |
rev | line source |
---|---|
16201
8250f2777afc
maint: update all copyright year number ranges
Jim Meyering <meyering@redhat.com>
parents:
14866
diff
changeset
|
1 /* Copyright (C) 1992, 1995-2003, 2005-2012 Free Software Foundation, Inc. |
4080 | 2 This file is part of the GNU C Library. |
574 | 3 |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8948
diff
changeset
|
4 This program is free software: you can redistribute it and/or modify |
4440
e58a1c05a6ba
Update gettext source files from gettext automatically, using srclist-update.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4156
diff
changeset
|
5 it under the terms of the GNU General Public License as published by |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8948
diff
changeset
|
6 the Free Software Foundation; either version 3 of the License, or |
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8948
diff
changeset
|
7 (at your option) any later version. |
574 | 8 |
4440
e58a1c05a6ba
Update gettext source files from gettext automatically, using srclist-update.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4156
diff
changeset
|
9 This program is distributed in the hope that it will be useful, |
4080 | 10 but WITHOUT ANY WARRANTY; without even the implied warranty of |
4440
e58a1c05a6ba
Update gettext source files from gettext automatically, using srclist-update.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4156
diff
changeset
|
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
e58a1c05a6ba
Update gettext source files from gettext automatically, using srclist-update.
Paul Eggert <eggert@cs.ucla.edu>
parents:
4156
diff
changeset
|
12 GNU General Public License for more details. |
574 | 13 |
9309
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8948
diff
changeset
|
14 You should have received a copy of the GNU General Public License |
bbbbbf4cd1c5
Change copyright notice from GPLv2+ to GPLv3+.
Bruno Haible <bruno@clisp.org>
parents:
8948
diff
changeset
|
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */ |
574 | 16 |
7302
8a1a9361108c
* _fpending.c: Include <config.h> unconditionally, since we no
Paul Eggert <eggert@cs.ucla.edu>
parents:
7074
diff
changeset
|
17 #if !_LIBC |
14542
62ec88367918
* lib/setenv.c (_GL_USE_STDLIB_ALLOC, malloc, realloc): Likewise.
Paul Eggert <eggert@cs.ucla.edu>
parents:
14079
diff
changeset
|
18 # define _GL_USE_STDLIB_ALLOC 1 |
653 | 19 # include <config.h> |
574 | 20 #endif |
12422
f7842310a565
New module 'arg-nonnull'. Declare which arguments expect non-NULL values.
Bruno Haible <bruno@clisp.org>
parents:
12421
diff
changeset
|
21 |
f7842310a565
New module 'arg-nonnull'. Declare which arguments expect non-NULL values.
Bruno Haible <bruno@clisp.org>
parents:
12421
diff
changeset
|
22 /* Don't use __attribute__ __nonnull__ in this compilation unit. Otherwise gcc |
f7842310a565
New module 'arg-nonnull'. Declare which arguments expect non-NULL values.
Bruno Haible <bruno@clisp.org>
parents:
12421
diff
changeset
|
23 optimizes away the name == NULL test below. */ |
f7842310a565
New module 'arg-nonnull'. Declare which arguments expect non-NULL values.
Bruno Haible <bruno@clisp.org>
parents:
12421
diff
changeset
|
24 #define _GL_ARG_NONNULL(params) |
f7842310a565
New module 'arg-nonnull'. Declare which arguments expect non-NULL values.
Bruno Haible <bruno@clisp.org>
parents:
12421
diff
changeset
|
25 |
4156
99ea86c79f44
Make it possibly to simply write: #include <alloca.h>.
Bruno Haible <bruno@clisp.org>
parents:
4080
diff
changeset
|
26 #include <alloca.h> |
4080 | 27 |
9545
c596ca4e89b4
Split setenv module into setenv and unsetenv. Get rid of setenv.h.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
28 /* Specification. */ |
c596ca4e89b4
Split setenv module into setenv and unsetenv. Get rid of setenv.h.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
29 #include <stdlib.h> |
c596ca4e89b4
Split setenv module into setenv and unsetenv. Get rid of setenv.h.
Bruno Haible <bruno@clisp.org>
parents:
9309
diff
changeset
|
30 |
574 | 31 #include <errno.h> |
5159 | 32 #ifndef __set_errno |
4080 | 33 # define __set_errno(ev) ((errno) = (ev)) |
34 #endif | |
574 | 35 |
4683
4452e4c45cc4
Assume ANSI C <string.h>, <stdlib.h>.
Bruno Haible <bruno@clisp.org>
parents:
4440
diff
changeset
|
36 #include <string.h> |
7074
75561a6a4a30
setenv.c comes from gettext / libiconv again.
Bruno Haible <bruno@clisp.org>
parents:
6711
diff
changeset
|
37 #if _LIBC || HAVE_UNISTD_H |
75561a6a4a30
setenv.c comes from gettext / libiconv again.
Bruno Haible <bruno@clisp.org>
parents:
6711
diff
changeset
|
38 # include <unistd.h> |
75561a6a4a30
setenv.c comes from gettext / libiconv again.
Bruno Haible <bruno@clisp.org>
parents:
6711
diff
changeset
|
39 #endif |
574 | 40 |
4929
4192ff0fff14
Use allocsa instead of alloca.
Bruno Haible <bruno@clisp.org>
parents:
4691
diff
changeset
|
41 #if !_LIBC |
8948
a162347a0232
Update after allocsa -> malloca renaming.
Bruno Haible <bruno@clisp.org>
parents:
8307
diff
changeset
|
42 # include "malloca.h" |
4080 | 43 #endif |
44 | |
12300
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
45 #if _LIBC || !HAVE_SETENV |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
46 |
4080 | 47 #if !_LIBC |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
48 # define __environ environ |
4080 | 49 #endif |
50 | |
51 #if _LIBC | |
16235
18a38c9615f0
In commentary, do not use ` to quote.
Paul Eggert <eggert@cs.ucla.edu>
parents:
16201
diff
changeset
|
52 /* This lock protects against simultaneous modifications of 'environ'. */ |
4080 | 53 # include <bits/libc-lock.h> |
54 __libc_lock_define_initialized (static, envlock) | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
55 # define LOCK __libc_lock_lock (envlock) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
56 # define UNLOCK __libc_lock_unlock (envlock) |
4080 | 57 #else |
58 # define LOCK | |
59 # define UNLOCK | |
60 #endif | |
61 | |
62 /* In the GNU C library we must keep the namespace clean. */ | |
63 #ifdef _LIBC | |
64 # define setenv __setenv | |
65 # define clearenv __clearenv | |
66 # define tfind __tfind | |
67 # define tsearch __tsearch | |
574 | 68 #endif |
69 | |
4080 | 70 /* In the GNU C library implementation we try to be more clever and |
71 allow arbitrarily many changes of the environment given that the used | |
72 values are from a small set. Outside glibc this will eat up all | |
73 memory after a while. */ | |
74 #if defined _LIBC || (defined HAVE_SEARCH_H && defined HAVE_TSEARCH \ | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
75 && defined __GNUC__) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
76 # define USE_TSEARCH 1 |
4080 | 77 # include <search.h> |
78 typedef int (*compar_fn_t) (const void *, const void *); | |
79 | |
80 /* This is a pointer to the root of the search tree with the known | |
81 values. */ | |
82 static void *known_values; | |
83 | |
84 # define KNOWN_VALUE(Str) \ | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
85 ({ \ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
86 void *value = tfind (Str, &known_values, (compar_fn_t) strcmp); \ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
87 value != NULL ? *(char **) value : NULL; \ |
4080 | 88 }) |
89 # define STORE_VALUE(Str) \ | |
90 tsearch (Str, &known_values, (compar_fn_t) strcmp) | |
91 | |
92 #else | |
93 # undef USE_TSEARCH | |
94 | |
95 # define KNOWN_VALUE(Str) NULL | |
96 # define STORE_VALUE(Str) do { } while (0) | |
97 | |
98 #endif | |
99 | |
100 | |
101 /* If this variable is not a null pointer we allocated the current | |
102 environment. */ | |
103 static char **last_environ; | |
104 | |
105 | |
16235
18a38c9615f0
In commentary, do not use ` to quote.
Paul Eggert <eggert@cs.ucla.edu>
parents:
16201
diff
changeset
|
106 /* This function is used by 'setenv' and 'putenv'. The difference between |
4080 | 107 the two functions is that for the former must create a new string which |
16235
18a38c9615f0
In commentary, do not use ` to quote.
Paul Eggert <eggert@cs.ucla.edu>
parents:
16201
diff
changeset
|
108 is then placed in the environment, while the argument of 'putenv' |
4080 | 109 must be used directly. This is all complicated by the fact that we try |
16235
18a38c9615f0
In commentary, do not use ` to quote.
Paul Eggert <eggert@cs.ucla.edu>
parents:
16201
diff
changeset
|
110 to reuse values once generated for a 'setenv' call since we can never |
4080 | 111 free the strings. */ |
574 | 112 int |
4080 | 113 __add_to_environ (const char *name, const char *value, const char *combined, |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
114 int replace) |
574 | 115 { |
13239
81bcdef18cd8
setenv: allow compilation with C++
Eric Blake <eblake@redhat.com>
parents:
12559
diff
changeset
|
116 char **ep; |
81bcdef18cd8
setenv: allow compilation with C++
Eric Blake <eblake@redhat.com>
parents:
12559
diff
changeset
|
117 size_t size; |
574 | 118 const size_t namelen = strlen (name); |
4080 | 119 const size_t vallen = value != NULL ? strlen (value) + 1 : 0; |
120 | |
121 LOCK; | |
122 | |
123 /* We have to get the pointer now that we have the lock and not earlier | |
124 since another thread might have created a new environment. */ | |
125 ep = __environ; | |
574 | 126 |
127 size = 0; | |
4080 | 128 if (ep != NULL) |
129 { | |
130 for (; *ep != NULL; ++ep) | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
131 if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=') |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
132 break; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
133 else |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
134 ++size; |
4080 | 135 } |
574 | 136 |
4080 | 137 if (ep == NULL || *ep == NULL) |
574 | 138 { |
139 char **new_environ; | |
4080 | 140 #ifdef USE_TSEARCH |
141 char *new_value; | |
142 #endif | |
574 | 143 |
4080 | 144 /* We allocated this space; we can extend it. */ |
145 new_environ = | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
146 (char **) (last_environ == NULL |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
147 ? malloc ((size + 2) * sizeof (char *)) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
148 : realloc (last_environ, (size + 2) * sizeof (char *))); |
574 | 149 if (new_environ == NULL) |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
150 { |
13394
6999c44d1f59
Module setenv does not depend on 'malloc-posix', 'realloc-posix'.
Bruno Haible <bruno@clisp.org>
parents:
13239
diff
changeset
|
151 /* It's easier to set errno to ENOMEM than to rely on the |
6999c44d1f59
Module setenv does not depend on 'malloc-posix', 'realloc-posix'.
Bruno Haible <bruno@clisp.org>
parents:
13239
diff
changeset
|
152 'malloc-posix' and 'realloc-posix' gnulib modules. */ |
6999c44d1f59
Module setenv does not depend on 'malloc-posix', 'realloc-posix'.
Bruno Haible <bruno@clisp.org>
parents:
13239
diff
changeset
|
153 __set_errno (ENOMEM); |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
154 UNLOCK; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
155 return -1; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
156 } |
4080 | 157 |
158 /* If the whole entry is given add it. */ | |
159 if (combined != NULL) | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
160 /* We must not add the string to the search tree since it belongs |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
161 to the user. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
162 new_environ[size] = (char *) combined; |
4080 | 163 else |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
164 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
165 /* See whether the value is already known. */ |
4080 | 166 #ifdef USE_TSEARCH |
4929
4192ff0fff14
Use allocsa instead of alloca.
Bruno Haible <bruno@clisp.org>
parents:
4691
diff
changeset
|
167 # ifdef _LIBC |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
168 new_value = (char *) alloca (namelen + 1 + vallen); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
169 __mempcpy (__mempcpy (__mempcpy (new_value, name, namelen), "=", 1), |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
170 value, vallen); |
4080 | 171 # else |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
172 new_value = (char *) malloca (namelen + 1 + vallen); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
173 if (new_value == NULL) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
174 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
175 __set_errno (ENOMEM); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
176 UNLOCK; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
177 return -1; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
178 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
179 memcpy (new_value, name, namelen); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
180 new_value[namelen] = '='; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
181 memcpy (&new_value[namelen + 1], value, vallen); |
4080 | 182 # endif |
574 | 183 |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
184 new_environ[size] = KNOWN_VALUE (new_value); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
185 if (new_environ[size] == NULL) |
4080 | 186 #endif |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
187 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
188 new_environ[size] = (char *) malloc (namelen + 1 + vallen); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
189 if (new_environ[size] == NULL) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
190 { |
4929
4192ff0fff14
Use allocsa instead of alloca.
Bruno Haible <bruno@clisp.org>
parents:
4691
diff
changeset
|
191 #if defined USE_TSEARCH && !defined _LIBC |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
192 freea (new_value); |
4080 | 193 #endif |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
194 __set_errno (ENOMEM); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
195 UNLOCK; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
196 return -1; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
197 } |
4080 | 198 |
199 #ifdef USE_TSEARCH | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
200 memcpy (new_environ[size], new_value, namelen + 1 + vallen); |
4080 | 201 #else |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
202 memcpy (new_environ[size], name, namelen); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
203 new_environ[size][namelen] = '='; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
204 memcpy (&new_environ[size][namelen + 1], value, vallen); |
4080 | 205 #endif |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
206 /* And save the value now. We cannot do this when we remove |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
207 the string since then we cannot decide whether it is a |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
208 user string or not. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
209 STORE_VALUE (new_environ[size]); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
210 } |
4929
4192ff0fff14
Use allocsa instead of alloca.
Bruno Haible <bruno@clisp.org>
parents:
4691
diff
changeset
|
211 #if defined USE_TSEARCH && !defined _LIBC |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
212 freea (new_value); |
4080 | 213 #endif |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
214 } |
574 | 215 |
216 if (__environ != last_environ) | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
217 memcpy ((char *) new_environ, (char *) __environ, |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
218 size * sizeof (char *)); |
574 | 219 |
220 new_environ[size + 1] = NULL; | |
221 | |
222 last_environ = __environ = new_environ; | |
223 } | |
224 else if (replace) | |
225 { | |
4080 | 226 char *np; |
227 | |
228 /* Use the user string if given. */ | |
229 if (combined != NULL) | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
230 np = (char *) combined; |
4080 | 231 else |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
232 { |
4080 | 233 #ifdef USE_TSEARCH |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
234 char *new_value; |
4080 | 235 # ifdef _LIBC |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
236 new_value = alloca (namelen + 1 + vallen); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
237 __mempcpy (__mempcpy (__mempcpy (new_value, name, namelen), "=", 1), |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
238 value, vallen); |
4080 | 239 # else |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
240 new_value = malloca (namelen + 1 + vallen); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
241 if (new_value == NULL) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
242 { |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
243 __set_errno (ENOMEM); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
244 UNLOCK; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
245 return -1; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
246 } |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
247 memcpy (new_value, name, namelen); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
248 new_value[namelen] = '='; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
249 memcpy (&new_value[namelen + 1], value, vallen); |
4080 | 250 # endif |
251 | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
252 np = KNOWN_VALUE (new_value); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
253 if (np == NULL) |
4080 | 254 #endif |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
255 { |
13239
81bcdef18cd8
setenv: allow compilation with C++
Eric Blake <eblake@redhat.com>
parents:
12559
diff
changeset
|
256 np = (char *) malloc (namelen + 1 + vallen); |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
257 if (np == NULL) |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
258 { |
4929
4192ff0fff14
Use allocsa instead of alloca.
Bruno Haible <bruno@clisp.org>
parents:
4691
diff
changeset
|
259 #if defined USE_TSEARCH && !defined _LIBC |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
260 freea (new_value); |
4080 | 261 #endif |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
262 __set_errno (ENOMEM); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
263 UNLOCK; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
264 return -1; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
265 } |
4080 | 266 |
267 #ifdef USE_TSEARCH | |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
268 memcpy (np, new_value, namelen + 1 + vallen); |
4080 | 269 #else |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
270 memcpy (np, name, namelen); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
271 np[namelen] = '='; |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
272 memcpy (&np[namelen + 1], value, vallen); |
4080 | 273 #endif |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
274 /* And remember the value. */ |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
275 STORE_VALUE (np); |
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
276 } |
4929
4192ff0fff14
Use allocsa instead of alloca.
Bruno Haible <bruno@clisp.org>
parents:
4691
diff
changeset
|
277 #if defined USE_TSEARCH && !defined _LIBC |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
278 freea (new_value); |
4080 | 279 #endif |
12421
e8d2c6fc33ad
Use spaces for indentation, not tabs.
Bruno Haible <bruno@clisp.org>
parents:
12300
diff
changeset
|
280 } |
4080 | 281 |
282 *ep = np; | |
574 | 283 } |
284 | |
4080 | 285 UNLOCK; |
286 | |
574 | 287 return 0; |
288 } | |
289 | |
4080 | 290 int |
291 setenv (const char *name, const char *value, int replace) | |
292 { | |
12300
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
293 if (name == NULL || *name == '\0' || strchr (name, '=') != NULL) |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
294 { |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
295 __set_errno (EINVAL); |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
296 return -1; |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
297 } |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
298 |
4080 | 299 return __add_to_environ (name, value, NULL, replace); |
300 } | |
301 | |
16235
18a38c9615f0
In commentary, do not use ` to quote.
Paul Eggert <eggert@cs.ucla.edu>
parents:
16201
diff
changeset
|
302 /* The 'clearenv' was planned to be added to POSIX.1 but probably |
4080 | 303 never made it. Nevertheless the POSIX.9 standard (POSIX bindings |
304 for Fortran 77) requires this function. */ | |
305 int | |
4691 | 306 clearenv (void) |
574 | 307 { |
4080 | 308 LOCK; |
309 | |
310 if (__environ == last_environ && __environ != NULL) | |
311 { | |
312 /* We allocated this environment so we can free it. */ | |
313 free (__environ); | |
314 last_environ = NULL; | |
315 } | |
316 | |
317 /* Clear the environment pointer removes the whole environment. */ | |
318 __environ = NULL; | |
574 | 319 |
4080 | 320 UNLOCK; |
321 | |
322 return 0; | |
574 | 323 } |
4080 | 324 |
325 #ifdef _LIBC | |
326 static void | |
327 free_mem (void) | |
328 { | |
329 /* Remove all traces. */ | |
330 clearenv (); | |
331 | |
332 /* Now remove the search tree. */ | |
333 __tdestroy (known_values, free); | |
334 known_values = NULL; | |
335 } | |
336 text_set_element (__libc_subfreeres, free_mem); | |
337 | |
338 | |
339 # undef setenv | |
340 # undef clearenv | |
341 weak_alias (__setenv, setenv) | |
342 weak_alias (__clearenv, clearenv) | |
343 #endif | |
8307
330dcd891960
Make it possible to compile setenv.c separately, unconditionally.
Bruno Haible <bruno@clisp.org>
parents:
7302
diff
changeset
|
344 |
330dcd891960
Make it possible to compile setenv.c separately, unconditionally.
Bruno Haible <bruno@clisp.org>
parents:
7302
diff
changeset
|
345 #endif /* _LIBC || !HAVE_SETENV */ |
12300
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
346 |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
347 /* The rest of this file is called into use when replacing an existing |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
348 but buggy setenv. Known bugs include failure to diagnose invalid |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
349 name, and consuming a leading '=' from value. */ |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
350 #if HAVE_SETENV |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
351 |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
352 # undef setenv |
14866
0d4d726862ca
setenv: Avoid gcc warning.
Bruno Haible <bruno@clisp.org>
parents:
14542
diff
changeset
|
353 # if !HAVE_DECL_SETENV |
0d4d726862ca
setenv: Avoid gcc warning.
Bruno Haible <bruno@clisp.org>
parents:
14542
diff
changeset
|
354 extern int setenv (const char *, const char *, int); |
0d4d726862ca
setenv: Avoid gcc warning.
Bruno Haible <bruno@clisp.org>
parents:
14542
diff
changeset
|
355 # endif |
12300
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
356 # define STREQ(a, b) (strcmp (a, b) == 0) |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
357 |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
358 int |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
359 rpl_setenv (const char *name, const char *value, int replace) |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
360 { |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
361 int result; |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
362 if (!name || !*name || strchr (name, '=')) |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
363 { |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
364 errno = EINVAL; |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
365 return -1; |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
366 } |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
367 /* Call the real setenv even if replace is 0, in case implementation |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
368 has underlying data to update, such as when environ changes. */ |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
369 result = setenv (name, value, replace); |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
370 if (result == 0 && replace && *value == '=') |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
371 { |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
372 char *tmp = getenv (name); |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
373 if (!STREQ (tmp, value)) |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
374 { |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
375 int saved_errno; |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
376 size_t len = strlen (value); |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
377 tmp = malloca (len + 2); |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
378 /* Since leading '=' is eaten, double it up. */ |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
379 *tmp = '='; |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
380 memcpy (tmp + 1, value, len + 1); |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
381 result = setenv (name, tmp, replace); |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
382 saved_errno = errno; |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
383 freea (tmp); |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
384 errno = saved_errno; |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
385 } |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
386 } |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
387 return result; |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
388 } |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
389 |
c8288fd3f281
setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents:
9721
diff
changeset
|
390 #endif /* HAVE_SETENV */ |