View | Details | Raw Unified | Return to bug 115094
Collapse All | Expand All

(-)files/patch-environ (+253 lines)
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 \

Return to bug 115094