This repository was archived by the owner on Feb 25, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathenv.c
More file actions
190 lines (168 loc) · 4 KB
/
env.c
File metadata and controls
190 lines (168 loc) · 4 KB
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
/* env.c, env.h: environ library
Daniel J. Bernstein, brnstnd@nyu.edu.
Depends on ralloc.h.
Requires strlen, strncmp, environ.
8/3/91: Fixed off-by-one [sigh] in env_put2().
7/24/91: Added env_put2(). Recoded in terms of ralloc macros.
7/18/91: Cleanups. env 1.1, public domain.
7/10/91: Was ralloc()ing too little; didn't init env right. Tnx CW/EW/HB.
6/29/91: Added env_unsetlen(), made env_add use it so string can be const.
6/28/91: Baseline. env 1.0, public domain.
No known patent problems.
Thanks to Christian Wettergren <d88-cwe@pdc.kth.se>, Erik Wallin
<d87-ewa@pdc.kth.se>, and Harald Barth <d88-hba@tds.kth.se> for bug
fixes.
This was originally meant as a portable version of putenv(). It expanded
to include unsetenv() and getenv(). Note that the routines always
maintain environ properly, so execvp() and friends will pick up the new
variables. I recommend that programs which do a lot of environment
manipulation work with strings and keep their own hash table, then use
these routines to manipulate environ before an execvp().
env_init() does optional initialization. It returns 0 on success, -1 on
failure. Note that env_init(), env_put(), and env_unset() may all change
environ.
env_put("FOO=BAR") adds FOO=BAR to the environment, destroying any
previous value of FOO. It returns 0 on success, -1 on failure. Note that
previous versions of env.c required env_put's argument to be writable;
this problem has been removed.
env_put2("FOO","BAR") is just like env_put("FOO=BAR"), except of course
that in the second case the new environment variable refers to the
string passed to env_put, while in the first case it refers to
internally malloc()ed memory.
env_unset("FOO") unsets any variable FOO. It returns 0 on success, -1 on
failure. It will always succeed if env_init() has previously succeeded.
env_get("FOO") returns the value of the first variable FOO, or 0 if
there is no such variable.
env_pick() returns any FOO=BAR in the environment, or 0 if the
environment is empty. This can be used to implement the BSD printenv
call, or to clear the environment.
*/
#include "env.h"
#include "ralloc.h"
static int init = 0;
static int numenv;
static int allocenv;
extern char *env_get(s)
char *s;
{
int i;
int slen;
char *envi;
slen = strlen(s);
for (i = 0;envi = environ[i];++i)
if ((!strncmp(s,envi,slen)) && (envi[slen] == '='))
return envi + slen + 1;
return 0;
}
extern char *env_pick()
{
return environ[0]; /* environ[numenv-1] would make (pick-unset)^n easier */
}
static void env_unsetlen(s,slen)
char *s;
int slen;
{
int i;
for (i = 0;i < numenv;++i)
if ((!strncmp(s,environ[i],slen)) && (environ[i][slen] == '='))
{
if (i < --numenv)
environ[i] = environ[numenv];
environ[numenv] = 0;
}
}
extern int env_unset(s)
char *s;
{
if (!init)
if (env_init())
return -1;
env_unsetlen(s,strlen(s));
return 0;
}
static int env_realloc()
{
char **envp;
allocenv = numenv + 30;
envp = environ;
environ = RALLOC(char *,allocenv + 1);
if (!environ)
{
environ = envp;
allocenv = numenv;
return -1;
}
numenv = 0;
while (*envp)
{
environ[numenv] = *envp;
++numenv;
++envp;
}
environ[numenv] = 0;
RFREE(envp - numenv);
return 0;
}
static int env_add(s)
char *s;
{
char *t;
for (t = s;*t;++t)
if (*t == '=')
{
env_unsetlen(s,t - s);
break;
}
if (numenv == allocenv)
if (env_realloc())
return -1;
environ[numenv] = s;
++numenv;
environ[numenv] = 0;
return 0;
}
int env_init()
{
char **envp;
numenv = 0;
allocenv = 0;
envp = environ;
environ = RALLOC(char *,1);
if (!environ)
{
environ = envp;
return -1;
}
environ[0] = 0;
init = 1;
while (*envp)
{
if (env_add(*envp))
return -1;
++envp;
}
return 0;
}
int env_put(s)
char *s;
{
if (!init)
if (env_init())
return -1;
return env_add(s);
}
int env_put2(s,t)
char *s;
char *t;
{
char *u;
int slen;
slen = strlen(s);
u = ralloc(slen + strlen(t) + 2);
if (!u)
return -1;
strcpy(u,s);
u[slen] = '=';
strcpy(u + slen + 1,t);
return env_put(u);
}