ports/115094: [PATCH] shells/zsh: fix for using *env()

Sean C. Farley scf at FreeBSD.org
Tue Jul 31 19:30:02 UTC 2007


>Number:         115094
>Category:       ports
>Synopsis:       [PATCH] shells/zsh: fix for using *env()
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-ports-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Tue Jul 31 19:30:01 GMT 2007
>Closed-Date:
>Last-Modified:
>Originator:     Sean C. Farley
>Release:        FreeBSD 6.2-STABLE i386
>Organization:
>Environment:
System: FreeBSD thor.farley.org 6.2-STABLE FreeBSD 6.2-STABLE #0: Sun Jul 29 21:02:21 CDT 2007
>Description:
This patch by Peter Stephenson adds (un)setenv() detection to zsh.  This
fixes the issue on 7-CURRENT where zsh was manipulating environ directly
in conflict with the new *env() functions.  6-STABLE continues to works
correctly.

See "zsh oddities with recent -current" for the initial report:
http://lists.freebsd.org/pipermail/freebsd-current/2007-July/075538.html

Here is the thread about the patch:
http://www.zsh.org/mla/workers/2007/msg00619.html

Notes:
- With the recent autoconf changes, I am not sure if the patches to both
  configure and configure.ac are needed.
- The patch to the test case is not really needed.
- The next version of zsh should have this fix in it.

Added file(s):
- files/patch-environ

Port maintainer (sergei at FreeBSD.org) is cc'd.

Generated with FreeBSD Port Tools 0.77
>How-To-Repeat:
>Fix:

--- zsh-4.3.4_1.patch begins here ---
Index: files/patch-environ
===================================================================
RCS file: files/patch-environ
diff -N files/patch-environ
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ files/patch-environ	31 Jul 2007 14:21:36 -0000
@@ -0,0 +1,253 @@
+diff -u Src/exec.c Src/exec.c
+--- Src/exec.c	2007-02-14 10:11:19.000000000 -0600
++++ Src/exec.c	2007-07-31 08:49:13.000000000 -0500
+@@ -501,7 +501,16 @@
+      * that as argv[0] for this external command       */
+     if (unset(RESTRICTED) && (z = zgetenv("ARGV0"))) {
+ 	setdata(firstnode(args), (void *) ztrdup(z));
++	/*
++	 * Note we don't do anything with the parameter structure
++	 * for ARGV0: that's OK since we're about to exec or exit
++	 * on failure.
++	 */
++#ifdef USE_SET_UNSET_ENV
++	unsetenv("ARGV0");
++#else
+ 	delenvvalue(z - 6);
++#endif
+     } else if (dash) {
+     /* Else if the pre-command `-' was given, we add `-' *
+      * to the front of argv[0] for this command.         */
+diff -u Src/params.c Src/params.c
+--- Src/params.c	2007-04-13 06:40:27.000000000 -0500
++++ Src/params.c	2007-07-31 08:49:13.000000000 -0500
+@@ -606,7 +606,7 @@
+ createparamtable(void)
+ {
+     Param ip, pm;
+-#ifndef HAVE_PUTENV
++#if !defined(HAVE_PUTENV) && !defined(USE_SET_UNSET_ENV)
+     char **new_environ;
+     int  envsize;
+ #endif
+@@ -661,7 +661,7 @@
+ 
+     setsparam("LOGNAME", ztrdup((str = getlogin()) && *str ? str :
cached_username));
+ 
+-#ifndef HAVE_PUTENV
++#if !defined(HAVE_PUTENV) && !defined(USE_SET_UNSET_ENV)
+     /* Copy the environment variables we are inheriting to dynamic *
+      * memory, so we can do mallocs and frees on it.               */
+     envsize = sizeof(char *)*(1 + arrlen(environ));
+@@ -3727,6 +3727,30 @@
+ int
+ zputenv(char *str)
+ {
++#ifdef USE_SET_UNSET_ENV
++    /*
++     * If we are using unsetenv() to remove values from the
++     * environment, which is the safe thing to do, we
++     * need to use setenv() to put them there in the first place.
++     * Unfortunately this is a slightly different interface
++     * from what zputenv() assumes.
++     */
++    char *ptr;
++    int ret;
++
++    for (ptr = str; *ptr && *ptr != '='; ptr++)
++	;
++    if (*ptr) {
++	*ptr = '\0';
++	ret = setenv(str, ptr+1, 1);
++	*ptr = '=';
++    } else {
++	/* safety first */
++	DPUTS(1, "bad environment string");
++	ret = setenv(str, ptr, 1);
++    }
++    return ret;
++#else
+ #ifdef HAVE_PUTENV
+     return putenv(str);
+ #else
+@@ -3750,9 +3774,12 @@
+     }
+     return 0;
+ #endif
++#endif
+ }
+ 
+ /**/
++#ifndef USE_SET_UNSET_ENV
++/**/
+ static int
+ findenv(char *name, int *pos)
+ {
+@@ -3771,6 +3798,8 @@
+     
+     return 0;
+ }
++/**/
++#endif
+ 
+ /* Given *name = "foo", it searches the environment for string *
+  * "foo=bar", and returns a pointer to the beginning of "bar"  */
+@@ -3811,14 +3840,18 @@
+ void
+ addenv(Param pm, char *value)
+ {
+-    char *oldenv = 0, *newenv = 0, *env = 0;
++    char *newenv = 0;
++#ifndef USE_SET_UNSET_ENV
++    char *oldenv = 0, *env = 0;
+     int pos;
+ 
+-    /* First check if there is already an environment *
+-     * variable matching string `name'. If not, and   *
+-     * we are not requested to add new, return        */
++    /*
++     * First check if there is already an environment
++     * variable matching string `name'.
++     */
+     if (findenv(pm->node.nam, &pos))
+ 	oldenv = environ[pos];
++#endif
+ 
+      newenv = mkenvstr(pm->node.nam, value, pm->node.flags);
+      if (zputenv(newenv)) {
+@@ -3826,6 +3859,19 @@
+ 	pm->env = NULL;
+ 	return;
+     }
++#ifdef USE_SET_UNSET_ENV
++     /*
++      * If we are using setenv/unsetenv to manage the environment,
++      * we simply store the string we created in pm->env since
++      * memory management of the environment is handled entirely
++      * by the system.
++      *
++      * TODO: is this good enough to fix problem cases from
++      * the other branch?  If so, we don't actually need to
++      * store pm->env at all, just a flag that the value was set.
++      */
++     pm->env = newenv;
++#else
+     /*
+      * Under Cygwin we must use putenv() to maintain consistency.
+      * Unfortunately, current version (1.1.2) copies argument and may
+@@ -3845,6 +3891,7 @@
+ 
+     DPUTS(1, "addenv should never reach the end");
+     pm->env = NULL;
++#endif
+ }
+ 
+ 
+@@ -3875,6 +3922,7 @@
+  * string.                                         */
+ 
+ 
++#ifndef USE_SET_UNSET_ENV
+ /**/
+ void
+ delenvvalue(char *x)
+@@ -3890,6 +3938,8 @@
+     }
+     zsfree(x);
+ }
++#endif
++
+ 
+ /* Delete a pointer from the list of pointers to environment *
+  * variables by shifting all the other pointers up one slot. */
+@@ -3898,7 +3948,12 @@
+ void
+ delenv(Param pm)
+ {
++#ifdef USE_SET_UNSET_ENV
++    unsetenv(pm->node.nam);
++    zsfree(pm->env);
++#else
+     delenvvalue(pm->env);
++#endif
+     pm->env = NULL;
+     /*
+      * Note we don't remove PM_EXPORT from the flags.  This
+diff -u Src/system.h Src/system.h
+--- Src/system.h	2007-04-13 05:11:31.000000000 -0500
++++ Src/system.h	2007-07-31 08:49:13.000000000 -0500
+@@ -693,6 +693,15 @@
+ 
+ extern char **environ;
+ 
++/*
++ * We always need setenv and unsetenv in pairs, because
++ * we don't know how to do memory management on the values set.
++ */
++#if defined(HAVE_SETENV) && defined(HAVE_UNSETENV)
++# define USE_SET_UNSET_ENV
++#endif
++
++
+ /* These variables are sometimes defined in, *
+  * and needed by, the termcap library.       */
+ #if MUST_DEFINE_OSPEED
+diff -u Test/B02typeset.ztst Test/B02typeset.ztst
+--- Test/B02typeset.ztst	2006-06-26 13:17:32.000000000 -0500
++++ Test/B02typeset.ztst	2007-07-31 08:49:13.000000000 -0500
+@@ -379,3 +379,31 @@
+ >integer local i
+ >local tagged scalar
+ >preserved
++
++ export ENVFOO=bar
++ print ENVFOO in environment
++ env | grep '^ENVFOO'
++ print Changing ENVFOO
++ ENVFOO="not bar any more"
++ env | grep '^ENVFOO'
++ unset ENVFOO
++ print ENVFOO no longer in environment
++ env | grep '^ENVFOO'
++1:Adding and removing values to and from the environment
++>ENVFOO in environment
++>ENVFOO=bar
++>Changing ENVFOO
++>ENVFOO=not bar any more
++>ENVFOO no longer in environment
++
++ (export FOOENV=BAR
++ env | grep '^FOOENV'
++ print Exec
++ exec $ZTST_testdir/../Src/zsh -c '
++ print Unset
++ unset FOOENV
++ env | grep "^FOOENV"')
++1:Can unset environment variables after exec
++>FOOENV=BAR
++>Exec
++>Unset
+diff -u configure configure
+--- configure	2007-01-18 10:33:17.000000000 -0600
++++ configure	2007-07-31 08:49:06.000000000 -0500
+@@ -10263,7 +10263,7 @@
+ 	       setlocale \
+ 	       uname \
+ 	       signgam \
+-	       putenv getenv \
++	       putenv getenv setenv unsetenv xw \
+ 	       brk sbrk \
+ 	       pathconf sysconf \
+ 	       tgetent tigetflag tigetnum tigetstr setupterm \
+diff -u configure.ac configure.ac
+--- configure.ac	2007-01-05 07:58:04.000000000 -0600
++++ configure.ac	2007-07-31 08:49:06.000000000 -0500
+@@ -1126,7 +1126,7 @@
+ 	       setlocale \
+ 	       uname \
+ 	       signgam \
+-	       putenv getenv \
++	       putenv getenv setenv unsetenv xw\
+ 	       brk sbrk \
+ 	       pathconf sysconf \
+ 	       tgetent tigetflag tigetnum tigetstr setupterm \
--- zsh-4.3.4_1.patch ends here ---
>Release-Note:
>Audit-Trail:
>Unformatted:



More information about the freebsd-ports-bugs mailing list