4
* Many systems have putenv() but no setenv(). Other systems have setenv() but
5
* no putenv() (MIPS). Still other systems have neither (NeXT). This is a
6
* re-implementation that hopefully ends all problems.
8
* Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
12
#ifdef MISSING_SETENV_PUTENV
18
extern char **environ;
20
static int addenv(char *); /* append entry to environment */
21
static int allocated = 0; /* environ is, or is not, allocated */
25
/* namelength - determine length of name in "name=whatever" */
27
static int namelength(const char *name)
31
equal = strchr(name, '=');
32
return ((equal == 0) ? strlen(name) : (equal - name));
35
/* findenv - given name, locate name=value */
37
static char **findenv(const char *name, int len)
41
for (envp = environ; envp && *envp; envp++)
42
if (strncmp(name, *envp, len) == 0 && (*envp)[len] == '=')
49
/* getenv - given name, locate value */
51
char *getenv(const char *name)
53
int len = namelength(name);
54
char **envp = findenv(name, len);
56
return (envp ? *envp + len + 1 : 0);
59
/* putenv - update or append environment (name,value) pair */
61
int putenv(const char *nameval)
63
char *equal = strchr(nameval, '=');
64
char *value = (equal ? equal : "");
66
return (setenv(nameval, value, DO_CLOBBER));
69
/* unsetenv - remove variable from environment */
71
void unsetenv(const char *name)
75
while ((envp = findenv(name, namelength(name))) != 0)
76
while (envp[0] = envp[1])
82
/* setenv - update or append environment (name,value) pair */
84
int setenv(const char *name, const char *value, int clobber)
88
int l_name; /* length of name part */
89
unsigned int l_nameval; /* length of name=value */
91
/* Permit name= and =value. */
93
l_name = namelength(name);
94
envp = findenv(name, l_name);
95
if (envp != 0 && clobber == 0)
99
l_nameval = l_name + strlen(value) + 1;
102
* Use available memory if the old value is long enough. Never free an
103
* old name=value entry because it may not be allocated.
106
destination = (envp != 0 && strlen(*envp) >= l_nameval) ?
107
*envp : malloc(l_nameval + 1);
108
if (destination == 0)
110
strncpy(destination, name, l_name);
111
destination[l_name] = '=';
112
strcpy(destination + l_name + 1, value);
113
return ((envp == 0) ? addenv(destination) : (*envp = destination, 0));
116
/* cmalloc - malloc and copy block of memory */
118
static char *cmalloc(int new_len, char *old, int old_len)
120
char *new = malloc(new_len);
123
memcpy(new, old, old_len);
127
/* addenv - append environment entry */
129
static int addenv(char *nameval)
132
int n_used; /* number of environment entries */
133
int l_used; /* bytes used excl. terminator */
134
int l_need; /* bytes needed incl. terminator */
136
for (envp = environ; envp && *envp; envp++)
138
n_used = envp - environ;
139
l_used = n_used * sizeof(*envp);
140
l_need = l_used + 2 * sizeof(*envp);
143
(char **) realloc((char *) environ, l_need) :
144
(char **) cmalloc(l_need, (char *) environ, l_used);
150
environ[n_used++] = nameval; /* add new entry */
151
environ[n_used] = 0; /* terminate list */