From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5897 invoked from network); 28 Jul 2000 08:50:54 -0000 Received: from sunsite.auc.dk (130.225.51.30) by ns1.primenet.com.au with SMTP; 28 Jul 2000 08:50:54 -0000 Received: (qmail 9695 invoked by alias); 28 Jul 2000 08:50:35 -0000 Mailing-List: contact zsh-workers-help@sunsite.auc.dk; run by ezmlm Precedence: bulk X-No-Archive: yes X-Seq: 12419 Received: (qmail 9688 invoked from network); 28 Jul 2000 08:50:34 -0000 X-Envelope-Sender-Is: Andrej.Borsenkow@mow.siemens.ru (at relayer david.siemens.de) From: "Andrej Borsenkow" To: "ZSH workers mailing list" Subject: PATCH: environment handling rewrite Date: Fri, 28 Jul 2000 12:50:29 +0400 Message-ID: <000501bff870$e1a9a400$21c9ca95@mow.siemens.ru> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_0006_01BFF892.68BB4400" X-Priority: 3 (Normal) X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook IMO, Build 9.0.2416 (9.0.2911.0) Importance: Normal X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4133.2400 This is a multi-part message in MIME format. ------=_NextPart_000_0006_01BFF892.68BB4400 Content-Type: text/plain; charset="koi8-r" Content-Transfer-Encoding: 7bit This rewrites environment handling to use system supplied putenv()/getenv() if available. The main reason was Cygwin, where internal environment management differs from Unix significantly. There is no system dependencies (apart from existence of environ). The only two assumptions are: - if environ table is extended, malloc() is used. - if putenv() copies it's argument, malloc() is used (it is the case under current Cygwin) Else it dynamically checks, if putenv() has reused old memory or copied it's argument. I'm running it on both Unix and Cygwin and it works so far. With exception of --enable-zsh-mem problem on Cygiwn, but ot cannot be related (error comes even before we set up environment). It depends on configure.in patch from my previous mail (patch for brk() on Cygwin). Could anybody commit them as I'd like to have clean state for Cygwin modules stuff? thanks -andrej Have a nice DOS! B >> ------=_NextPart_000_0006_01BFF892.68BB4400 Content-Type: application/octet-stream; name="zsh-env.diff" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="zsh-env.diff" Index: Src/builtin.c=0A= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= RCS file: /cvsroot/zsh/zsh/Src/builtin.c,v=0A= retrieving revision 1.29=0A= diff -u -r1.29 builtin.c=0A= --- Src/builtin.c 2000/07/19 20:43:51 1.29=0A= +++ Src/builtin.c 2000/07/27 16:49:14=0A= @@ -1634,7 +1634,6 @@=0A= pm->env =3D addenv(pname, getsparam(pname), pm->flags);=0A= } else if (pm->env && !(pm->flags & PM_HASHELEM)) {=0A= delenv(pm->env);=0A= - zsfree(pm->env);=0A= pm->env =3D NULL;=0A= }=0A= if (value)=0A= @@ -1711,7 +1710,6 @@=0A= tpm->ct =3D pm->ct;=0A= if (pm->env) {=0A= delenv(pm->env);=0A= - zsfree(pm->env);=0A= }=0A= tpm->env =3D pm->env =3D NULL;=0A= =0A= Index: Src/params.c=0A= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=0A= RCS file: /cvsroot/zsh/zsh/Src/params.c,v=0A= retrieving revision 1.23=0A= diff -u -r1.23 params.c=0A= --- Src/params.c 2000/07/13 17:06:19 1.23=0A= +++ Src/params.c 2000/07/27 16:49:18=0A= @@ -455,10 +455,13 @@=0A= createparamtable(void)=0A= {=0A= Param ip, pm;=0A= - char **new_environ, **envp, **envp2, **sigptr, **t;=0A= - char **old_environ =3D environ;=0A= +#ifndef HAVE_PUTENV=0A= + char **new_environ;=0A= + int envsize;=0A= +#endif=0A= + char **envp, **envp2, **sigptr, **t;=0A= char buf[50], *str, *iname, *hostnam;=0A= - int num_env, oae =3D opts[ALLEXPORT];=0A= + int oae =3D opts[ALLEXPORT];=0A= #ifdef HAVE_UNAME=0A= struct utsname unamebuf;=0A= char *machinebuf;=0A= @@ -501,15 +504,19 @@=0A= =0A= setsparam("LOGNAME", ztrdup((str =3D getlogin()) && *str ? str : = cached_username));=0A= =0A= +#ifndef HAVE_PUTENV=0A= /* Copy the environment variables we are inheriting to dynamic *=0A= * memory, so we can do mallocs and frees on it. */=0A= - num_env =3D arrlen(environ);=0A= - new_environ =3D (char **) zalloc(sizeof(char *) * (num_env + 1));=0A= - *new_environ =3D NULL;=0A= + envsize =3D sizeof(char *)*(1 + arrlen(environ));=0A= + new_environ =3D (char **) zalloc(envsize);=0A= + memcpy (new_environ, environ, envsize);=0A= + environ =3D new_environ;=0A= +#endif=0A= =0A= /* Now incorporate environment variables we are inheriting *=0A= - * into the parameter hash table. */=0A= - for (envp =3D new_environ, envp2 =3D environ; *envp2; envp2++) {=0A= + * into the parameter hash table. Copy them into dynamic *=0A= + * memory so that we can free them if needed */=0A= + for (envp =3D envp2 =3D environ; *envp2; envp2++) {=0A= for (str =3D *envp2; *str && *str !=3D '=3D'; str++);=0A= if (*str =3D=3D '=3D') {=0A= iname =3D NULL;=0A= @@ -517,25 +524,22 @@=0A= if (!idigit(**envp2) && isident(*envp2) && !strchr(*envp2, '[')) {=0A= iname =3D *envp2;=0A= if ((!(pm =3D (Param) paramtab->getnode(paramtab, iname)) ||=0A= - !(pm->flags & PM_DONTIMPORT)) &&=0A= - (pm =3D setsparam(iname, metafy(str + 1, -1, META_DUP))) &&=0A= - !(pm->flags & PM_EXPORTED)) {=0A= + !(pm->flags & PM_DONTIMPORT || pm->flags & PM_EXPORTED)) &&=0A= + (pm =3D setsparam(iname, metafy(str + 1, -1, META_DUP)))) {=0A= *str =3D '=3D';=0A= pm->flags |=3D PM_EXPORTED;=0A= - pm->env =3D *envp++ =3D ztrdup(*envp2);=0A= - *envp =3D NULL;=0A= - if (pm->flags & PM_SPECIAL) {=0A= - environ =3D new_environ;=0A= - pm->env =3D replenv(pm->env, getsparam(pm->nam),=0A= - pm->flags);=0A= - environ =3D old_environ;=0A= - }=0A= + if (pm->flags & PM_SPECIAL)=0A= + pm->env =3D mkenvstr (pm->nam,=0A= + getsparam(pm->nam), pm->flags);=0A= + else=0A= + pm->env =3D ztrdup(*envp2);=0A= + *envp++ =3D pm->env;=0A= }=0A= }=0A= *str =3D '=3D';=0A= }=0A= }=0A= - environ =3D new_environ;=0A= + *envp =3D '\0';=0A= opts[ALLEXPORT] =3D oae;=0A= =0A= pm =3D (Param) paramtab->getnode(paramtab, "HOME");=0A= @@ -660,7 +664,6 @@=0A= */=0A= if (oldpm->env) {=0A= delenv(oldpm->env);=0A= - zsfree(oldpm->env);=0A= oldpm->env =3D NULL;=0A= }=0A= paramtab->removenode(paramtab, name);=0A= @@ -1489,7 +1492,7 @@=0A= else=0A= val =3D pm->gets.cfn(pm);=0A= if (pm->env)=0A= - pm->env =3D replenv(pm->env, val, pm->flags);=0A= + pm->env =3D replenv(pm->nam, val, pm->flags);=0A= else {=0A= pm->flags |=3D PM_EXPORTED;=0A= pm->env =3D addenv(pm->nam, val, pm->flags);=0A= @@ -2006,7 +2009,6 @@=0A= pm->unsetfn(pm, exp);=0A= if ((pm->flags & PM_EXPORTED) && pm->env) {=0A= delenv(pm->env);=0A= - zsfree(pm->env);=0A= pm->env =3D NULL;=0A= }=0A= =0A= @@ -2824,8 +2826,7 @@=0A= void=0A= arrfixenv(char *s, char **t)=0A= {=0A= - char **ep, *u;=0A= - int len_s;=0A= + char *u;=0A= Param pm;=0A= =0A= pm =3D (Param) paramtab->getnode(paramtab, s);=0A= @@ -2838,24 +2839,47 @@=0A= if (pm->flags & PM_HASHELEM)=0A= return;=0A= u =3D t ? zjoin(t, ':', 1) : "";=0A= - len_s =3D strlen(s);=0A= - for (ep =3D environ; *ep; ep++)=0A= - if (!strncmp(*ep, s, len_s) && (*ep)[len_s] =3D=3D '=3D') {=0A= - pm->env =3D replenv(*ep, u, pm->flags);=0A= - return;=0A= - }=0A= + if (findenv(s, 0)) {=0A= + pm->env =3D replenv(s, u, pm->flags);=0A= + return;=0A= + }=0A= if (isset(ALLEXPORT))=0A= pm->flags |=3D PM_EXPORTED;=0A= if (pm->flags & PM_EXPORTED)=0A= pm->env =3D addenv(s, u, pm->flags);=0A= }=0A= =0A= -/* Given *name =3D "foo", it searchs the environment for string *=0A= - * "foo=3Dbar", and returns a pointer to the beginning of "bar" */=0A= +#ifndef HAVE_PUTENV=0A= =0A= -/**/=0A= -mod_export char *=0A= -zgetenv(char *name)=0A= +static int=0A= +putenv(char *str)=0A= +{=0A= + char **ep;=0A= + int num_env;=0A= +=0A= +=0A= + /* First check if there is already an environment *=0A= + * variable matching string `name'. */=0A= + if (findenv (str, &num_env)) {=0A= + environ[num_env] =3D str;=0A= + } else {=0A= + /* Else we have to make room and add it */=0A= + num_env =3D arrlen(environ);=0A= + environ =3D (char **) zrealloc(environ, (sizeof(char *)) * (num_env + = 2));=0A= +=0A= + /* Now add it at the end */=0A= + ep =3D environ + num_env;=0A= + *ep =3D str;=0A= + *(ep + 1) =3D NULL;=0A= + }=0A= + return 0;=0A= +}=0A= +#endif=0A= +=0A= +#ifndef HAVE_GETENV=0A= +=0A= +static char *=0A= +getenv(char *name)=0A= {=0A= char **ep, *s, *t;=0A= =0A= @@ -2866,6 +2890,37 @@=0A= }=0A= return NULL;=0A= }=0A= +#endif=0A= +=0A= +/**/=0A= +static int=0A= +findenv (char *name, int *pos)=0A= +{=0A= + char **ep, *eq;=0A= + int nlen;=0A= +=0A= +=0A= + eq =3D strchr (name, '=3D');=0A= + nlen =3D eq ? eq - name : strlen (name);=0A= + for (ep =3D environ; *ep; ep++) =0A= + if (!strncmp (*ep, name, nlen) && *((*ep)+nlen) =3D=3D '=3D') {=0A= + if (pos)=0A= + *pos =3D ep - environ;=0A= + return 1;=0A= + }=0A= + =0A= + return 0;=0A= +}=0A= +=0A= +/* Given *name =3D "foo", it searchs the environment for string *=0A= + * "foo=3Dbar", and returns a pointer to the beginning of "bar" */=0A= +=0A= +/**/=0A= +mod_export char *=0A= +zgetenv(char *name)=0A= +{=0A= + return getenv(name);=0A= +}=0A= =0A= /**/=0A= static void=0A= @@ -2881,27 +2936,51 @@=0A= }=0A= }=0A= =0A= +static char *=0A= +addenv_internal(char *name, char *value, int flags, int add)=0A= +{=0A= + char *oldenv =3D 0, *newenv =3D 0, *env =3D 0;=0A= + int pos;=0A= +=0A= + /* First check if there is already an environment *=0A= + * variable matching string `name'. If not, and *=0A= + * we are not requested to add new, return */=0A= + if (findenv (name, &pos))=0A= + oldenv =3D environ[pos];=0A= + else if (!add)=0A= + return NULL;=0A= +=0A= + newenv =3D mkenvstr (name, value, flags);=0A= + if (putenv (newenv)) {=0A= + zsfree (newenv);=0A= + return NULL;=0A= + }=0A= + /*=0A= + * Under Cygwin we must use putenv() to maintain consistency.=0A= + * Unfortunately, current version (1.1.2) copies argument and may=0A= + * silently reuse exisiting environment string. This tries to=0A= + * check for both cases=0A= + */=0A= + if (findenv (name, &pos)) {=0A= + env =3D environ[pos];=0A= + if (env !=3D oldenv)=0A= + zsfree (oldenv);=0A= + if (env !=3D newenv)=0A= + zsfree (newenv);=0A= + return env;=0A= + }=0A= +=0A= + return NULL; /* Cannot happen */=0A= +}=0A= +=0A= /* Change the value of an existing environment variable */=0A= =0A= /**/=0A= char *=0A= -replenv(char *e, char *value, int flags)=0A= +replenv(char *name, char *value, int flags)=0A= {=0A= - char **ep, *s;=0A= - int len_value;=0A= =0A= - for (ep =3D environ; *ep; ep++)=0A= - if (*ep =3D=3D e) {=0A= - for (len_value =3D 0, s =3D value;=0A= - *s && (*s++ !=3D Meta || *s++ !=3D 32); len_value++);=0A= - s =3D e;=0A= - while (*s++ !=3D '=3D');=0A= - *ep =3D (char *) zrealloc(e, s - e + len_value + 1);=0A= - s =3D s - e + *ep - 1;=0A= - copyenvstr(s, value, flags);=0A= - return *ep;=0A= - }=0A= - return NULL;=0A= + return addenv_internal (name, value, flags, 0);=0A= }=0A= =0A= /* Given strings *name =3D "foo", *value =3D "bar", *=0A= @@ -2934,28 +3013,7 @@=0A= char *=0A= addenv(char *name, char *value, int flags)=0A= {=0A= - char **ep, *s, *t;=0A= - int num_env;=0A= -=0A= - /* First check if there is already an environment *=0A= - * variable matching string `name'. */=0A= - for (ep =3D environ; *ep; ep++) {=0A= - for (s =3D *ep, t =3D name; *s && *s =3D=3D *t; s++, t++);=0A= - if (*s =3D=3D '=3D' && !*t) {=0A= - zsfree(*ep);=0A= - return *ep =3D mkenvstr(name, value, flags);=0A= - }=0A= - }=0A= -=0A= - /* Else we have to make room and add it */=0A= - num_env =3D arrlen(environ);=0A= - environ =3D (char **) zrealloc(environ, (sizeof(char *)) * (num_env = + 2));=0A= -=0A= - /* Now add it at the end */=0A= - ep =3D environ + num_env;=0A= - *ep =3D mkenvstr(name, value, flags);=0A= - *(ep + 1) =3D NULL;=0A= - return *ep;=0A= + return addenv_internal (name, value, flags, 1);=0A= }=0A= =0A= /* Delete a pointer from the list of pointers to environment *=0A= @@ -2971,8 +3029,10 @@=0A= if (*ep =3D=3D x)=0A= break;=0A= }=0A= - if (*ep)=0A= + if (*ep) {=0A= for (; (ep[0] =3D ep[1]); ep++);=0A= + }=0A= + zsfree(x);=0A= }=0A= =0A= /**/=0A= @@ -3105,7 +3165,6 @@=0A= pm->ct =3D tpm->ct;=0A= if (pm->env) {=0A= delenv(pm->env);=0A= - zsfree(pm->env);=0A= }=0A= pm->env =3D NULL;=0A= =0A= ------=_NextPart_000_0006_01BFF892.68BB4400--