annotate lib/setenv.c @ 12300:c8288fd3f281

setenv, unsetenv: work around various bugs POSIX requires setenv(NULL,"",0), setenv("a=b","",0), unsetenv(NULL), and unsetenv("a=b") to fail with EINVAL, but many BSD implementations lack validation. The gnulib replacement for void unsetenv did not do validation, and the replacement for setenv was out of sync with glibc. Also, some BSD implementations of setenv("a","==",1) eat the leading '='. See also some recent Austin Group interpretations on environ: http://austingroupbugs.net/view.php?id=167 http://austingroupbugs.net/view.php?id=185 * lib/setenv.c (setenv) [!HAVE_SETENV]: Resync from glibc. (setenv) [HAVE_SETENV]: Work around bugs. * lib/unsetenv.c (unsetenv) [HAVE_UNSETENV]: Work around bugs. * m4/setenv.m4 (gl_FUNC_SETENV_SEPARATE, gl_FUNC_UNSETENV): Check for bugs. (gl_FUNC_SETENV): Write in terms of gl_FUNC_SETENV_SEPARATE. * m4/environ.m4 (gl_ENVIRON): Avoid expand-before-require. * m4/stdlib_h.m4 (gl_STDLIB_H_DEFAULTS): Update defaults. * modules/stdlib (Makefile.am): Update substitutions. * lib/stdlib.in.h (setenv, unsetenv): Update prototypes. * doc/posix-functions/setenv.texi (setenv): Document the bugs. * doc/posix-functions/unsetenv.texi (unsetenv): Likewise. * modules/setenv-tests: New test. * modules/unsetenv-tests: Likewise. * tests/test-setenv.c: New file. * tests/test-unsetenv.c: Likewise. Signed-off-by: Eric Blake <ebb9@byu.net>
author Eric Blake <ebb9@byu.net>
date Sat, 14 Nov 2009 22:13:10 -0700
parents 1d443a80afc4
children e8d2c6fc33ad
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
12300
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
1 /* Copyright (C) 1992,1995-1999,2000-2003,2005-2009 Free Software Foundation, Inc.
4080
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
2 This file is part of the GNU C Library.
574
Jim Meyering <jim@meyering.net>
parents:
diff changeset
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
Jim Meyering <jim@meyering.net>
parents:
diff changeset
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
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
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
Jim Meyering <jim@meyering.net>
parents:
diff changeset
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
Jim Meyering <jim@meyering.net>
parents:
diff changeset
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
653
b63f146fd963 indent cpp-directives
Jim Meyering <jim@meyering.net>
parents: 576
diff changeset
18 # include <config.h>
574
Jim Meyering <jim@meyering.net>
parents:
diff changeset
19 #endif
4156
99ea86c79f44 Make it possibly to simply write: #include <alloca.h>.
Bruno Haible <bruno@clisp.org>
parents: 4080
diff changeset
20 #include <alloca.h>
4080
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
21
9545
c596ca4e89b4 Split setenv module into setenv and unsetenv. Get rid of setenv.h.
Bruno Haible <bruno@clisp.org>
parents: 9309
diff changeset
22 /* Specification. */
c596ca4e89b4 Split setenv module into setenv and unsetenv. Get rid of setenv.h.
Bruno Haible <bruno@clisp.org>
parents: 9309
diff changeset
23 #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
24
574
Jim Meyering <jim@meyering.net>
parents:
diff changeset
25 #include <errno.h>
5159
a535859efd14 Merge from coreutils.
Paul Eggert <eggert@cs.ucla.edu>
parents: 4929
diff changeset
26 #ifndef __set_errno
4080
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
27 # define __set_errno(ev) ((errno) = (ev))
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
28 #endif
574
Jim Meyering <jim@meyering.net>
parents:
diff changeset
29
4683
4452e4c45cc4 Assume ANSI C <string.h>, <stdlib.h>.
Bruno Haible <bruno@clisp.org>
parents: 4440
diff changeset
30 #include <string.h>
7074
75561a6a4a30 setenv.c comes from gettext / libiconv again.
Bruno Haible <bruno@clisp.org>
parents: 6711
diff changeset
31 #if _LIBC || HAVE_UNISTD_H
75561a6a4a30 setenv.c comes from gettext / libiconv again.
Bruno Haible <bruno@clisp.org>
parents: 6711
diff changeset
32 # include <unistd.h>
75561a6a4a30 setenv.c comes from gettext / libiconv again.
Bruno Haible <bruno@clisp.org>
parents: 6711
diff changeset
33 #endif
574
Jim Meyering <jim@meyering.net>
parents:
diff changeset
34
4929
4192ff0fff14 Use allocsa instead of alloca.
Bruno Haible <bruno@clisp.org>
parents: 4691
diff changeset
35 #if !_LIBC
8948
a162347a0232 Update after allocsa -> malloca renaming.
Bruno Haible <bruno@clisp.org>
parents: 8307
diff changeset
36 # include "malloca.h"
4080
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
37 #endif
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
38
12300
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
39 #if _LIBC || !HAVE_SETENV
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
40
4080
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
41 #if !_LIBC
2718
5994c6f939c5 update copyright date
Jim Meyering <jim@meyering.net>
parents: 653
diff changeset
42 # define __environ environ
4080
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
43 #endif
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
44
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
45 #if _LIBC
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
46 /* This lock protects against simultaneous modifications of `environ'. */
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
47 # include <bits/libc-lock.h>
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
48 __libc_lock_define_initialized (static, envlock)
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
49 # define LOCK __libc_lock_lock (envlock)
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
50 # define UNLOCK __libc_lock_unlock (envlock)
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
51 #else
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
52 # define LOCK
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
53 # define UNLOCK
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
54 #endif
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
55
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
56 /* In the GNU C library we must keep the namespace clean. */
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
57 #ifdef _LIBC
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
58 # define setenv __setenv
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
59 # define clearenv __clearenv
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
60 # define tfind __tfind
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
61 # define tsearch __tsearch
574
Jim Meyering <jim@meyering.net>
parents:
diff changeset
62 #endif
Jim Meyering <jim@meyering.net>
parents:
diff changeset
63
4080
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
64 /* In the GNU C library implementation we try to be more clever and
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
65 allow arbitrarily many changes of the environment given that the used
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
66 values are from a small set. Outside glibc this will eat up all
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
67 memory after a while. */
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
68 #if defined _LIBC || (defined HAVE_SEARCH_H && defined HAVE_TSEARCH \
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
69 && defined __GNUC__)
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
70 # define USE_TSEARCH 1
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
71 # include <search.h>
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
72 typedef int (*compar_fn_t) (const void *, const void *);
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
73
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
74 /* This is a pointer to the root of the search tree with the known
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
75 values. */
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
76 static void *known_values;
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
77
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
78 # define KNOWN_VALUE(Str) \
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
79 ({ \
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
80 void *value = tfind (Str, &known_values, (compar_fn_t) strcmp); \
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
81 value != NULL ? *(char **) value : NULL; \
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
82 })
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
83 # define STORE_VALUE(Str) \
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
84 tsearch (Str, &known_values, (compar_fn_t) strcmp)
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
85
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
86 #else
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
87 # undef USE_TSEARCH
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
88
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
89 # define KNOWN_VALUE(Str) NULL
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
90 # define STORE_VALUE(Str) do { } while (0)
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
91
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
92 #endif
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
93
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
94
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
95 /* If this variable is not a null pointer we allocated the current
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
96 environment. */
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
97 static char **last_environ;
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
98
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
99
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
100 /* This function is used by `setenv' and `putenv'. The difference between
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
101 the two functions is that for the former must create a new string which
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
102 is then placed in the environment, while the argument of `putenv'
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
103 must be used directly. This is all complicated by the fact that we try
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
104 to reuse values once generated for a `setenv' call since we can never
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
105 free the strings. */
574
Jim Meyering <jim@meyering.net>
parents:
diff changeset
106 int
4080
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
107 __add_to_environ (const char *name, const char *value, const char *combined,
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
108 int replace)
574
Jim Meyering <jim@meyering.net>
parents:
diff changeset
109 {
Jim Meyering <jim@meyering.net>
parents:
diff changeset
110 register char **ep;
Jim Meyering <jim@meyering.net>
parents:
diff changeset
111 register size_t size;
Jim Meyering <jim@meyering.net>
parents:
diff changeset
112 const size_t namelen = strlen (name);
4080
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
113 const size_t vallen = value != NULL ? strlen (value) + 1 : 0;
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
114
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
115 LOCK;
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
116
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
117 /* We have to get the pointer now that we have the lock and not earlier
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
118 since another thread might have created a new environment. */
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
119 ep = __environ;
574
Jim Meyering <jim@meyering.net>
parents:
diff changeset
120
Jim Meyering <jim@meyering.net>
parents:
diff changeset
121 size = 0;
4080
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
122 if (ep != NULL)
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
123 {
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
124 for (; *ep != NULL; ++ep)
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
125 if (!strncmp (*ep, name, namelen) && (*ep)[namelen] == '=')
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
126 break;
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
127 else
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
128 ++size;
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
129 }
574
Jim Meyering <jim@meyering.net>
parents:
diff changeset
130
4080
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
131 if (ep == NULL || *ep == NULL)
574
Jim Meyering <jim@meyering.net>
parents:
diff changeset
132 {
Jim Meyering <jim@meyering.net>
parents:
diff changeset
133 char **new_environ;
4080
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
134 #ifdef USE_TSEARCH
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
135 char *new_value;
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
136 #endif
574
Jim Meyering <jim@meyering.net>
parents:
diff changeset
137
4080
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
138 /* We allocated this space; we can extend it. */
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
139 new_environ =
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
140 (char **) (last_environ == NULL
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
141 ? malloc ((size + 2) * sizeof (char *))
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
142 : realloc (last_environ, (size + 2) * sizeof (char *)));
574
Jim Meyering <jim@meyering.net>
parents:
diff changeset
143 if (new_environ == NULL)
4080
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
144 {
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
145 UNLOCK;
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
146 return -1;
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
147 }
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
148
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
149 /* If the whole entry is given add it. */
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
150 if (combined != NULL)
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
151 /* We must not add the string to the search tree since it belongs
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
152 to the user. */
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
153 new_environ[size] = (char *) combined;
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
154 else
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
155 {
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
156 /* See whether the value is already known. */
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
157 #ifdef USE_TSEARCH
4929
4192ff0fff14 Use allocsa instead of alloca.
Bruno Haible <bruno@clisp.org>
parents: 4691
diff changeset
158 # ifdef _LIBC
4080
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
159 new_value = (char *) alloca (namelen + 1 + vallen);
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
160 __mempcpy (__mempcpy (__mempcpy (new_value, name, namelen), "=", 1),
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
161 value, vallen);
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
162 # else
8948
a162347a0232 Update after allocsa -> malloca renaming.
Bruno Haible <bruno@clisp.org>
parents: 8307
diff changeset
163 new_value = (char *) malloca (namelen + 1 + vallen);
4929
4192ff0fff14 Use allocsa instead of alloca.
Bruno Haible <bruno@clisp.org>
parents: 4691
diff changeset
164 if (new_value == NULL)
4192ff0fff14 Use allocsa instead of alloca.
Bruno Haible <bruno@clisp.org>
parents: 4691
diff changeset
165 {
4192ff0fff14 Use allocsa instead of alloca.
Bruno Haible <bruno@clisp.org>
parents: 4691
diff changeset
166 __set_errno (ENOMEM);
4192ff0fff14 Use allocsa instead of alloca.
Bruno Haible <bruno@clisp.org>
parents: 4691
diff changeset
167 UNLOCK;
4192ff0fff14 Use allocsa instead of alloca.
Bruno Haible <bruno@clisp.org>
parents: 4691
diff changeset
168 return -1;
4192ff0fff14 Use allocsa instead of alloca.
Bruno Haible <bruno@clisp.org>
parents: 4691
diff changeset
169 }
4080
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
170 memcpy (new_value, name, namelen);
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
171 new_value[namelen] = '=';
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
172 memcpy (&new_value[namelen + 1], value, vallen);
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
173 # endif
574
Jim Meyering <jim@meyering.net>
parents:
diff changeset
174
4080
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
175 new_environ[size] = KNOWN_VALUE (new_value);
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
176 if (new_environ[size] == NULL)
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
177 #endif
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
178 {
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
179 new_environ[size] = (char *) malloc (namelen + 1 + vallen);
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
180 if (new_environ[size] == NULL)
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
181 {
4929
4192ff0fff14 Use allocsa instead of alloca.
Bruno Haible <bruno@clisp.org>
parents: 4691
diff changeset
182 #if defined USE_TSEARCH && !defined _LIBC
8948
a162347a0232 Update after allocsa -> malloca renaming.
Bruno Haible <bruno@clisp.org>
parents: 8307
diff changeset
183 freea (new_value);
4080
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
184 #endif
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
185 __set_errno (ENOMEM);
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
186 UNLOCK;
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
187 return -1;
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
188 }
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
189
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
190 #ifdef USE_TSEARCH
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
191 memcpy (new_environ[size], new_value, namelen + 1 + vallen);
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
192 #else
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
193 memcpy (new_environ[size], name, namelen);
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
194 new_environ[size][namelen] = '=';
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
195 memcpy (&new_environ[size][namelen + 1], value, vallen);
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
196 #endif
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
197 /* And save the value now. We cannot do this when we remove
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
198 the string since then we cannot decide whether it is a
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
199 user string or not. */
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
200 STORE_VALUE (new_environ[size]);
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
201 }
4929
4192ff0fff14 Use allocsa instead of alloca.
Bruno Haible <bruno@clisp.org>
parents: 4691
diff changeset
202 #if defined USE_TSEARCH && !defined _LIBC
8948
a162347a0232 Update after allocsa -> malloca renaming.
Bruno Haible <bruno@clisp.org>
parents: 8307
diff changeset
203 freea (new_value);
4080
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
204 #endif
574
Jim Meyering <jim@meyering.net>
parents:
diff changeset
205 }
Jim Meyering <jim@meyering.net>
parents:
diff changeset
206
Jim Meyering <jim@meyering.net>
parents:
diff changeset
207 if (__environ != last_environ)
Jim Meyering <jim@meyering.net>
parents:
diff changeset
208 memcpy ((char *) new_environ, (char *) __environ,
Jim Meyering <jim@meyering.net>
parents:
diff changeset
209 size * sizeof (char *));
Jim Meyering <jim@meyering.net>
parents:
diff changeset
210
Jim Meyering <jim@meyering.net>
parents:
diff changeset
211 new_environ[size + 1] = NULL;
Jim Meyering <jim@meyering.net>
parents:
diff changeset
212
Jim Meyering <jim@meyering.net>
parents:
diff changeset
213 last_environ = __environ = new_environ;
Jim Meyering <jim@meyering.net>
parents:
diff changeset
214 }
Jim Meyering <jim@meyering.net>
parents:
diff changeset
215 else if (replace)
Jim Meyering <jim@meyering.net>
parents:
diff changeset
216 {
4080
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
217 char *np;
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
218
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
219 /* Use the user string if given. */
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
220 if (combined != NULL)
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
221 np = (char *) combined;
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
222 else
574
Jim Meyering <jim@meyering.net>
parents:
diff changeset
223 {
4080
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
224 #ifdef USE_TSEARCH
4929
4192ff0fff14 Use allocsa instead of alloca.
Bruno Haible <bruno@clisp.org>
parents: 4691
diff changeset
225 char *new_value;
4080
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
226 # ifdef _LIBC
4929
4192ff0fff14 Use allocsa instead of alloca.
Bruno Haible <bruno@clisp.org>
parents: 4691
diff changeset
227 new_value = alloca (namelen + 1 + vallen);
4080
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
228 __mempcpy (__mempcpy (__mempcpy (new_value, name, namelen), "=", 1),
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
229 value, vallen);
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
230 # else
8948
a162347a0232 Update after allocsa -> malloca renaming.
Bruno Haible <bruno@clisp.org>
parents: 8307
diff changeset
231 new_value = malloca (namelen + 1 + vallen);
4929
4192ff0fff14 Use allocsa instead of alloca.
Bruno Haible <bruno@clisp.org>
parents: 4691
diff changeset
232 if (new_value == NULL)
4192ff0fff14 Use allocsa instead of alloca.
Bruno Haible <bruno@clisp.org>
parents: 4691
diff changeset
233 {
4192ff0fff14 Use allocsa instead of alloca.
Bruno Haible <bruno@clisp.org>
parents: 4691
diff changeset
234 __set_errno (ENOMEM);
4192ff0fff14 Use allocsa instead of alloca.
Bruno Haible <bruno@clisp.org>
parents: 4691
diff changeset
235 UNLOCK;
4192ff0fff14 Use allocsa instead of alloca.
Bruno Haible <bruno@clisp.org>
parents: 4691
diff changeset
236 return -1;
4192ff0fff14 Use allocsa instead of alloca.
Bruno Haible <bruno@clisp.org>
parents: 4691
diff changeset
237 }
4080
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
238 memcpy (new_value, name, namelen);
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
239 new_value[namelen] = '=';
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
240 memcpy (&new_value[namelen + 1], value, vallen);
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
241 # endif
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
242
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
243 np = KNOWN_VALUE (new_value);
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
244 if (np == NULL)
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
245 #endif
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
246 {
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
247 np = malloc (namelen + 1 + vallen);
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
248 if (np == NULL)
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
249 {
4929
4192ff0fff14 Use allocsa instead of alloca.
Bruno Haible <bruno@clisp.org>
parents: 4691
diff changeset
250 #if defined USE_TSEARCH && !defined _LIBC
8948
a162347a0232 Update after allocsa -> malloca renaming.
Bruno Haible <bruno@clisp.org>
parents: 8307
diff changeset
251 freea (new_value);
4080
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
252 #endif
4929
4192ff0fff14 Use allocsa instead of alloca.
Bruno Haible <bruno@clisp.org>
parents: 4691
diff changeset
253 __set_errno (ENOMEM);
4080
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
254 UNLOCK;
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
255 return -1;
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
256 }
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
257
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
258 #ifdef USE_TSEARCH
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
259 memcpy (np, new_value, namelen + 1 + vallen);
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
260 #else
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
261 memcpy (np, name, namelen);
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
262 np[namelen] = '=';
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
263 memcpy (&np[namelen + 1], value, vallen);
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
264 #endif
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
265 /* And remember the value. */
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
266 STORE_VALUE (np);
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
267 }
4929
4192ff0fff14 Use allocsa instead of alloca.
Bruno Haible <bruno@clisp.org>
parents: 4691
diff changeset
268 #if defined USE_TSEARCH && !defined _LIBC
8948
a162347a0232 Update after allocsa -> malloca renaming.
Bruno Haible <bruno@clisp.org>
parents: 8307
diff changeset
269 freea (new_value);
4080
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
270 #endif
574
Jim Meyering <jim@meyering.net>
parents:
diff changeset
271 }
4080
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
272
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
273 *ep = np;
574
Jim Meyering <jim@meyering.net>
parents:
diff changeset
274 }
Jim Meyering <jim@meyering.net>
parents:
diff changeset
275
4080
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
276 UNLOCK;
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
277
574
Jim Meyering <jim@meyering.net>
parents:
diff changeset
278 return 0;
Jim Meyering <jim@meyering.net>
parents:
diff changeset
279 }
Jim Meyering <jim@meyering.net>
parents:
diff changeset
280
4080
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
281 int
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
282 setenv (const char *name, const char *value, int replace)
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
283 {
12300
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
284 if (name == NULL || *name == '\0' || strchr (name, '=') != NULL)
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
285 {
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
286 __set_errno (EINVAL);
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
287 return -1;
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
288 }
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
289
4080
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
290 return __add_to_environ (name, value, NULL, replace);
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
291 }
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
292
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
293 /* The `clearenv' was planned to be added to POSIX.1 but probably
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
294 never made it. Nevertheless the POSIX.9 standard (POSIX bindings
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
295 for Fortran 77) requires this function. */
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
296 int
4691
ce37d22a271f Remove K&R cruft.
Paul Eggert <eggert@cs.ucla.edu>
parents: 4683
diff changeset
297 clearenv (void)
574
Jim Meyering <jim@meyering.net>
parents:
diff changeset
298 {
4080
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
299 LOCK;
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
300
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
301 if (__environ == last_environ && __environ != NULL)
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
302 {
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
303 /* We allocated this environment so we can free it. */
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
304 free (__environ);
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
305 last_environ = NULL;
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
306 }
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
307
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
308 /* Clear the environment pointer removes the whole environment. */
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
309 __environ = NULL;
574
Jim Meyering <jim@meyering.net>
parents:
diff changeset
310
4080
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
311 UNLOCK;
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
312
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
313 return 0;
574
Jim Meyering <jim@meyering.net>
parents:
diff changeset
314 }
4080
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
315
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
316 #ifdef _LIBC
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
317 static void
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
318 free_mem (void)
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
319 {
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
320 /* Remove all traces. */
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
321 clearenv ();
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
322
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
323 /* Now remove the search tree. */
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
324 __tdestroy (known_values, free);
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
325 known_values = NULL;
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
326 }
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
327 text_set_element (__libc_subfreeres, free_mem);
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
328
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
329
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
330 # undef setenv
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
331 # undef clearenv
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
332 weak_alias (__setenv, setenv)
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
333 weak_alias (__clearenv, clearenv)
d064e5107035 setenv and unsetenv.
Bruno Haible <bruno@clisp.org>
parents: 2718
diff changeset
334 #endif
8307
330dcd891960 Make it possible to compile setenv.c separately, unconditionally.
Bruno Haible <bruno@clisp.org>
parents: 7302
diff changeset
335
330dcd891960 Make it possible to compile setenv.c separately, unconditionally.
Bruno Haible <bruno@clisp.org>
parents: 7302
diff changeset
336 #endif /* _LIBC || !HAVE_SETENV */
12300
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
337
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
338 /* 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
339 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
340 name, and consuming a leading '=' from value. */
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
341 #if HAVE_SETENV
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
342
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
343 # undef setenv
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
344 # define STREQ(a, b) (strcmp (a, b) == 0)
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
345
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
346 int
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
347 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
348 {
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
349 int result;
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
350 if (!name || !*name || strchr (name, '='))
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 errno = EINVAL;
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
353 return -1;
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
354 }
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
355 /* 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
356 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
357 result = setenv (name, value, replace);
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
358 if (result == 0 && replace && *value == '=')
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
359 {
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
360 char *tmp = getenv (name);
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
361 if (!STREQ (tmp, value))
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
362 {
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
363 int saved_errno;
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
364 size_t len = strlen (value);
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
365 tmp = malloca (len + 2);
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
366 /* Since leading '=' is eaten, double it up. */
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
367 *tmp = '=';
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
368 memcpy (tmp + 1, value, len + 1);
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
369 result = setenv (name, tmp, replace);
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
370 saved_errno = errno;
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
371 freea (tmp);
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
372 errno = saved_errno;
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
373 }
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 return result;
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
376 }
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
377
c8288fd3f281 setenv, unsetenv: work around various bugs
Eric Blake <ebb9@byu.net>
parents: 9721
diff changeset
378 #endif /* HAVE_SETENV */