]> git.ipfire.org Git - thirdparty/bash.git/blame - lib/sh/getenv.c
fix for SIGINT in sourced script
[thirdparty/bash.git] / lib / sh / getenv.c
CommitLineData
cce855bc
JA
1/* getenv.c - get environment variable value from the shell's variable
2 list. */
3
7117c2d2 4/* Copyright (C) 1997-2002 Free Software Foundation, Inc.
cce855bc
JA
5
6 This file is part of GNU Bash, the Bourne Again SHell.
7
3185942a
JA
8 Bash is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
cce855bc 12
3185942a
JA
13 Bash is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
cce855bc 17
3185942a
JA
18 You should have received a copy of the GNU General Public License
19 along with Bash. If not, see <http://www.gnu.org/licenses/>.
20*/
cce855bc
JA
21
22#include <config.h>
23
24#if defined (CAN_REDEFINE_GETENV)
25
26#if defined (HAVE_UNISTD_H)
27# include <unistd.h>
28#endif
29
30#include <bashansi.h>
7117c2d2 31#include <errno.h>
cce855bc
JA
32#include <shell.h>
33
7117c2d2
JA
34#ifndef errno
35extern int errno;
36#endif
37
cce855bc
JA
38extern char **environ;
39
40/* We supply our own version of getenv () because we want library
41 routines to get the changed values of exported variables. */
42
43/* The NeXT C library has getenv () defined and used in the same file.
44 This screws our scheme. However, Bash will run on the NeXT using
45 the C library getenv (), since right now the only environment variable
46 that we care about is HOME, and that is already defined. */
47static char *last_tempenv_value = (char *)NULL;
48
49char *
50getenv (name)
cce855bc 51 const char *name;
cce855bc
JA
52{
53 SHELL_VAR *var;
54
7117c2d2
JA
55 if (name == 0 || *name == '\0')
56 return ((char *)NULL);
57
cce855bc
JA
58 var = find_tempenv_variable ((char *)name);
59 if (var)
60 {
61 FREE (last_tempenv_value);
62
bb70624e 63 last_tempenv_value = value_cell (var) ? savestring (value_cell (var)) : (char *)NULL;
cce855bc
JA
64 return (last_tempenv_value);
65 }
66 else if (shell_variables)
67 {
68 var = find_variable ((char *)name);
69 if (var && exported_p (var))
70 return (value_cell (var));
71 }
72 else
73 {
74 register int i, len;
75
76 /* In some cases, s5r3 invokes getenv() before main(); BSD systems
77 using gprof also exhibit this behavior. This means that
78 shell_variables will be 0 when this is invoked. We look up the
79 variable in the real environment in that case. */
80
81 for (i = 0, len = strlen (name); environ[i]; i++)
82 {
83 if ((STREQN (environ[i], name, len)) && (environ[i][len] == '='))
84 return (environ[i] + len + 1);
85 }
86 }
87
88 return ((char *)NULL);
89}
90
91/* Some versions of Unix use _getenv instead. */
92char *
93_getenv (name)
cce855bc 94 const char *name;
cce855bc
JA
95{
96 return (getenv (name));
97}
7117c2d2
JA
98
99/* SUSv3 says argument is a `char *'; BSD implementations disagree */
100int
101putenv (str)
102#ifndef HAVE_STD_PUTENV
103 const char *str;
104#else
105 char *str;
106#endif
107{
108 SHELL_VAR *var;
109 char *name, *value;
110 int offset;
111
112 if (str == 0 || *str == '\0')
113 {
114 errno = EINVAL;
115 return -1;
116 }
117
b80f6443 118 offset = assignment (str, 0);
7117c2d2
JA
119 if (str[offset] != '=')
120 {
121 errno = EINVAL;
122 return -1;
123 }
124 name = savestring (str);
125 name[offset] = 0;
126
127 value = name + offset + 1;
128
129 /* XXX - should we worry about readonly here? */
95732b49 130 var = bind_variable (name, value, 0);
7117c2d2
JA
131 if (var == 0)
132 {
133 errno = EINVAL;
134 return -1;
135 }
136
137 VUNSETATTR (var, att_invisible);
138 VSETATTR (var, att_exported);
139
140 return 0;
141}
142
143#if 0
144int
145_putenv (name)
146#ifndef HAVE_STD_PUTENV
147 const char *name;
148#else
149 char *name;
150#endif
151{
152 return putenv (name);
153}
154#endif
155
156int
157setenv (name, value, rewrite)
158 const char *name;
159 const char *value;
160 int rewrite;
161{
162 SHELL_VAR *var;
163 char *v;
164
165 if (name == 0 || *name == '\0' || strchr (name, '=') != 0)
166 {
167 errno = EINVAL;
168 return -1;
169 }
170
171 var = 0;
b80f6443 172 v = (char *)value; /* some compilers need explicit cast */
7117c2d2
JA
173 /* XXX - should we worry about readonly here? */
174 if (rewrite == 0)
175 var = find_variable (name);
176
177 if (var == 0)
95732b49 178 var = bind_variable (name, v, 0);
7117c2d2
JA
179
180 if (var == 0)
181 return -1;
182
183 VUNSETATTR (var, att_invisible);
184 VSETATTR (var, att_exported);
185
186 return 0;
187}
188
189#if 0
190int
191_setenv (name, value, rewrite)
192 const char *name;
193 const char *value;
194 int rewrite;
195{
196 return setenv (name, value, rewrite);
197}
198#endif
199
200/* SUSv3 says unsetenv returns int; existing implementations (BSD) disagree. */
201
202#ifdef HAVE_STD_UNSETENV
203#define UNSETENV_RETURN(N) return(N)
204#define UNSETENV_RETTYPE int
205#else
206#define UNSETENV_RETURN(N) return
207#define UNSETENV_RETTYPE void
208#endif
209
210UNSETENV_RETTYPE
211unsetenv (name)
212 const char *name;
213{
214 if (name == 0 || *name == '\0' || strchr (name, '=') != 0)
215 {
216 errno = EINVAL;
217 UNSETENV_RETURN(-1);
218 }
219
220 /* XXX - should we just remove the export attribute here? */
221#if 1
222 unbind_variable (name);
223#else
224 SHELL_VAR *v;
225
226 v = find_variable (name);
227 if (v)
228 VUNSETATTR (v, att_exported);
229#endif
230
231 UNSETENV_RETURN(0);
232}
cce855bc 233#endif /* CAN_REDEFINE_GETENV */