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