Added
Link Here
|
1 |
diff -u Src/exec.c Src/exec.c |
2 |
--- Src/exec.c 2007-02-14 10:11:19.000000000 -0600 |
3 |
+++ Src/exec.c 2007-07-31 08:49:13.000000000 -0500 |
4 |
@@ -501,7 +501,16 @@ |
5 |
* that as argv[0] for this external command */ |
6 |
if (unset(RESTRICTED) && (z = zgetenv("ARGV0"))) { |
7 |
setdata(firstnode(args), (void *) ztrdup(z)); |
8 |
+ /* |
9 |
+ * Note we don't do anything with the parameter structure |
10 |
+ * for ARGV0: that's OK since we're about to exec or exit |
11 |
+ * on failure. |
12 |
+ */ |
13 |
+#ifdef USE_SET_UNSET_ENV |
14 |
+ unsetenv("ARGV0"); |
15 |
+#else |
16 |
delenvvalue(z - 6); |
17 |
+#endif |
18 |
} else if (dash) { |
19 |
/* Else if the pre-command `-' was given, we add `-' * |
20 |
* to the front of argv[0] for this command. */ |
21 |
diff -u Src/params.c Src/params.c |
22 |
--- Src/params.c 2007-04-13 06:40:27.000000000 -0500 |
23 |
+++ Src/params.c 2007-07-31 08:49:13.000000000 -0500 |
24 |
@@ -606,7 +606,7 @@ |
25 |
createparamtable(void) |
26 |
{ |
27 |
Param ip, pm; |
28 |
-#ifndef HAVE_PUTENV |
29 |
+#if !defined(HAVE_PUTENV) && !defined(USE_SET_UNSET_ENV) |
30 |
char **new_environ; |
31 |
int envsize; |
32 |
#endif |
33 |
@@ -661,7 +661,7 @@ |
34 |
|
35 |
setsparam("LOGNAME", ztrdup((str = getlogin()) && *str ? str : |
36 |
|
37 |
-#ifndef HAVE_PUTENV |
38 |
+#if !defined(HAVE_PUTENV) && !defined(USE_SET_UNSET_ENV) |
39 |
/* Copy the environment variables we are inheriting to dynamic * |
40 |
* memory, so we can do mallocs and frees on it. */ |
41 |
envsize = sizeof(char *)*(1 + arrlen(environ)); |
42 |
@@ -3727,6 +3727,30 @@ |
43 |
int |
44 |
zputenv(char *str) |
45 |
{ |
46 |
+#ifdef USE_SET_UNSET_ENV |
47 |
+ /* |
48 |
+ * If we are using unsetenv() to remove values from the |
49 |
+ * environment, which is the safe thing to do, we |
50 |
+ * need to use setenv() to put them there in the first place. |
51 |
+ * Unfortunately this is a slightly different interface |
52 |
+ * from what zputenv() assumes. |
53 |
+ */ |
54 |
+ char *ptr; |
55 |
+ int ret; |
56 |
+ |
57 |
+ for (ptr = str; *ptr && *ptr != '='; ptr++) |
58 |
+ ; |
59 |
+ if (*ptr) { |
60 |
+ *ptr = '\0'; |
61 |
+ ret = setenv(str, ptr+1, 1); |
62 |
+ *ptr = '='; |
63 |
+ } else { |
64 |
+ /* safety first */ |
65 |
+ DPUTS(1, "bad environment string"); |
66 |
+ ret = setenv(str, ptr, 1); |
67 |
+ } |
68 |
+ return ret; |
69 |
+#else |
70 |
#ifdef HAVE_PUTENV |
71 |
return putenv(str); |
72 |
#else |
73 |
@@ -3750,9 +3774,12 @@ |
74 |
} |
75 |
return 0; |
76 |
#endif |
77 |
+#endif |
78 |
} |
79 |
|
80 |
/**/ |
81 |
+#ifndef USE_SET_UNSET_ENV |
82 |
+/**/ |
83 |
static int |
84 |
findenv(char *name, int *pos) |
85 |
{ |
86 |
@@ -3771,6 +3798,8 @@ |
87 |
|
88 |
return 0; |
89 |
} |
90 |
+/**/ |
91 |
+#endif |
92 |
|
93 |
/* Given *name = "foo", it searches the environment for string * |
94 |
* "foo=bar", and returns a pointer to the beginning of "bar" */ |
95 |
@@ -3811,14 +3840,18 @@ |
96 |
void |
97 |
addenv(Param pm, char *value) |
98 |
{ |
99 |
- char *oldenv = 0, *newenv = 0, *env = 0; |
100 |
+ char *newenv = 0; |
101 |
+#ifndef USE_SET_UNSET_ENV |
102 |
+ char *oldenv = 0, *env = 0; |
103 |
int pos; |
104 |
|
105 |
- /* First check if there is already an environment * |
106 |
- * variable matching string `name'. If not, and * |
107 |
- * we are not requested to add new, return */ |
108 |
+ /* |
109 |
+ * First check if there is already an environment |
110 |
+ * variable matching string `name'. |
111 |
+ */ |
112 |
if (findenv(pm->node.nam, &pos)) |
113 |
oldenv = environ[pos]; |
114 |
+#endif |
115 |
|
116 |
newenv = mkenvstr(pm->node.nam, value, pm->node.flags); |
117 |
if (zputenv(newenv)) { |
118 |
@@ -3826,6 +3859,19 @@ |
119 |
pm->env = NULL; |
120 |
return; |
121 |
} |
122 |
+#ifdef USE_SET_UNSET_ENV |
123 |
+ /* |
124 |
+ * If we are using setenv/unsetenv to manage the environment, |
125 |
+ * we simply store the string we created in pm->env since |
126 |
+ * memory management of the environment is handled entirely |
127 |
+ * by the system. |
128 |
+ * |
129 |
+ * TODO: is this good enough to fix problem cases from |
130 |
+ * the other branch? If so, we don't actually need to |
131 |
+ * store pm->env at all, just a flag that the value was set. |
132 |
+ */ |
133 |
+ pm->env = newenv; |
134 |
+#else |
135 |
/* |
136 |
* Under Cygwin we must use putenv() to maintain consistency. |
137 |
* Unfortunately, current version (1.1.2) copies argument and may |
138 |
@@ -3845,6 +3891,7 @@ |
139 |
|
140 |
DPUTS(1, "addenv should never reach the end"); |
141 |
pm->env = NULL; |
142 |
+#endif |
143 |
} |
144 |
|
145 |
|
146 |
@@ -3875,6 +3922,7 @@ |
147 |
* string. */ |
148 |
|
149 |
|
150 |
+#ifndef USE_SET_UNSET_ENV |
151 |
/**/ |
152 |
void |
153 |
delenvvalue(char *x) |
154 |
@@ -3890,6 +3938,8 @@ |
155 |
} |
156 |
zsfree(x); |
157 |
} |
158 |
+#endif |
159 |
+ |
160 |
|
161 |
/* Delete a pointer from the list of pointers to environment * |
162 |
* variables by shifting all the other pointers up one slot. */ |
163 |
@@ -3898,7 +3948,12 @@ |
164 |
void |
165 |
delenv(Param pm) |
166 |
{ |
167 |
+#ifdef USE_SET_UNSET_ENV |
168 |
+ unsetenv(pm->node.nam); |
169 |
+ zsfree(pm->env); |
170 |
+#else |
171 |
delenvvalue(pm->env); |
172 |
+#endif |
173 |
pm->env = NULL; |
174 |
/* |
175 |
* Note we don't remove PM_EXPORT from the flags. This |
176 |
diff -u Src/system.h Src/system.h |
177 |
--- Src/system.h 2007-04-13 05:11:31.000000000 -0500 |
178 |
+++ Src/system.h 2007-07-31 08:49:13.000000000 -0500 |
179 |
@@ -693,6 +693,15 @@ |
180 |
|
181 |
extern char **environ; |
182 |
|
183 |
+/* |
184 |
+ * We always need setenv and unsetenv in pairs, because |
185 |
+ * we don't know how to do memory management on the values set. |
186 |
+ */ |
187 |
+#if defined(HAVE_SETENV) && defined(HAVE_UNSETENV) |
188 |
+# define USE_SET_UNSET_ENV |
189 |
+#endif |
190 |
+ |
191 |
+ |
192 |
/* These variables are sometimes defined in, * |
193 |
* and needed by, the termcap library. */ |
194 |
#if MUST_DEFINE_OSPEED |
195 |
diff -u Test/B02typeset.ztst Test/B02typeset.ztst |
196 |
--- Test/B02typeset.ztst 2006-06-26 13:17:32.000000000 -0500 |
197 |
+++ Test/B02typeset.ztst 2007-07-31 08:49:13.000000000 -0500 |
198 |
@@ -379,3 +379,31 @@ |
199 |
>integer local i |
200 |
>local tagged scalar |
201 |
>preserved |
202 |
+ |
203 |
+ export ENVFOO=bar |
204 |
+ print ENVFOO in environment |
205 |
+ env | grep '^ENVFOO' |
206 |
+ print Changing ENVFOO |
207 |
+ ENVFOO="not bar any more" |
208 |
+ env | grep '^ENVFOO' |
209 |
+ unset ENVFOO |
210 |
+ print ENVFOO no longer in environment |
211 |
+ env | grep '^ENVFOO' |
212 |
+1:Adding and removing values to and from the environment |
213 |
+>ENVFOO in environment |
214 |
+>ENVFOO=bar |
215 |
+>Changing ENVFOO |
216 |
+>ENVFOO=not bar any more |
217 |
+>ENVFOO no longer in environment |
218 |
+ |
219 |
+ (export FOOENV=BAR |
220 |
+ env | grep '^FOOENV' |
221 |
+ print Exec |
222 |
+ exec $ZTST_testdir/../Src/zsh -c ' |
223 |
+ print Unset |
224 |
+ unset FOOENV |
225 |
+ env | grep "^FOOENV"') |
226 |
+1:Can unset environment variables after exec |
227 |
+>FOOENV=BAR |
228 |
+>Exec |
229 |
+>Unset |
230 |
diff -u configure configure |
231 |
--- configure 2007-01-18 10:33:17.000000000 -0600 |
232 |
+++ configure 2007-07-31 08:49:06.000000000 -0500 |
233 |
@@ -10263,7 +10263,7 @@ |
234 |
setlocale \ |
235 |
uname \ |
236 |
signgam \ |
237 |
- putenv getenv \ |
238 |
+ putenv getenv setenv unsetenv xw \ |
239 |
brk sbrk \ |
240 |
pathconf sysconf \ |
241 |
tgetent tigetflag tigetnum tigetstr setupterm \ |
242 |
diff -u configure.ac configure.ac |
243 |
--- configure.ac 2007-01-05 07:58:04.000000000 -0600 |
244 |
+++ configure.ac 2007-07-31 08:49:06.000000000 -0500 |
245 |
@@ -1126,7 +1126,7 @@ |
246 |
setlocale \ |
247 |
uname \ |
248 |
signgam \ |
249 |
- putenv getenv \ |
250 |
+ putenv getenv setenv unsetenv xw\ |
251 |
brk sbrk \ |
252 |
pathconf sysconf \ |
253 |
tgetent tigetflag tigetnum tigetstr setupterm \ |