1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2024-06-01 21:06:04 +02:00

23725: use setenv()/unsetenv() for environment memory management

This commit is contained in:
Peter Stephenson 2007-07-30 20:46:04 +00:00
parent 378c2c7ae7
commit 1ab7d0fd0b
5 changed files with 88 additions and 7 deletions

View File

@ -1,3 +1,9 @@
2007-07-30 Peter Stephenson <p.w.stephenson@ntlworld.com>
* 23725: configure.ac, Src/exec.c, Src/params.c, Src/system.h:
use setenv() and unsetenv() for memory management of the
environment where possible.
2007-07-29 Clint Adams <clint@zsh.org> 2007-07-29 Clint Adams <clint@zsh.org>
* 23720: Completion/Unix/Command/_dvi: handle arguments to dvips -P * 23720: Completion/Unix/Command/_dvi: handle arguments to dvips -P

View File

@ -524,7 +524,16 @@ execute(LinkList args, int flags, int defpath)
* that as argv[0] for this external command */ * that as argv[0] for this external command */
if (unset(RESTRICTED) && (z = zgetenv("ARGV0"))) { if (unset(RESTRICTED) && (z = zgetenv("ARGV0"))) {
setdata(firstnode(args), (void *) ztrdup(z)); 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 HAVE_UNSETENV
unsetenv("ARGV0");
#else
delenvvalue(z - 6); delenvvalue(z - 6);
#endif
} else if (flags & BINF_DASH) { } else if (flags & BINF_DASH) {
/* Else if the pre-command `-' was given, we add `-' * /* Else if the pre-command `-' was given, we add `-' *
* to the front of argv[0] for this command. */ * to the front of argv[0] for this command. */

View File

@ -610,7 +610,7 @@ void
createparamtable(void) createparamtable(void)
{ {
Param ip, pm; Param ip, pm;
#ifndef HAVE_PUTENV #if !defined(HAVE_PUTENV) && !defined(HAVE_SETENV)
char **new_environ; char **new_environ;
int envsize; int envsize;
#endif #endif
@ -665,7 +665,7 @@ createparamtable(void)
setsparam("LOGNAME", ztrdup((str = getlogin()) && *str ? str : cached_username)); setsparam("LOGNAME", ztrdup((str = getlogin()) && *str ? str : cached_username));
#ifndef HAVE_PUTENV #if !defined(HAVE_PUTENV) && !defined(HAVE_SETENV)
/* Copy the environment variables we are inheriting to dynamic * /* Copy the environment variables we are inheriting to dynamic *
* memory, so we can do mallocs and frees on it. */ * memory, so we can do mallocs and frees on it. */
envsize = sizeof(char *)*(1 + arrlen(environ)); envsize = sizeof(char *)*(1 + arrlen(environ));
@ -3855,6 +3855,30 @@ arrfixenv(char *s, char **t)
int int
zputenv(char *str) zputenv(char *str)
{ {
#ifdef HAVE_SETENV
/*
* 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 #ifdef HAVE_PUTENV
return putenv(str); return putenv(str);
#else #else
@ -3878,8 +3902,11 @@ zputenv(char *str)
} }
return 0; return 0;
#endif #endif
#endif
} }
/**/
#ifndef HAVE_UNSETENV
/**/ /**/
static int static int
findenv(char *name, int *pos) findenv(char *name, int *pos)
@ -3899,6 +3926,8 @@ findenv(char *name, int *pos)
return 0; return 0;
} }
/**/
#endif
/* Given *name = "foo", it searches the environment for string * /* Given *name = "foo", it searches the environment for string *
* "foo=bar", and returns a pointer to the beginning of "bar" */ * "foo=bar", and returns a pointer to the beginning of "bar" */
@ -3939,14 +3968,20 @@ copyenvstr(char *s, char *value, int flags)
void void
addenv(Param pm, char *value) addenv(Param pm, char *value)
{ {
char *oldenv = 0, *newenv = 0, *env = 0; char *newenv = 0;
#ifndef HAVE_UNSETENV
char *oldenv = 0, *env = 0;
int pos; int pos;
#endif
/* First check if there is already an environment * #ifndef HAVE_UNSETENV
* 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)) if (findenv(pm->node.nam, &pos))
oldenv = environ[pos]; oldenv = environ[pos];
#endif
newenv = mkenvstr(pm->node.nam, value, pm->node.flags); newenv = mkenvstr(pm->node.nam, value, pm->node.flags);
if (zputenv(newenv)) { if (zputenv(newenv)) {
@ -3954,6 +3989,19 @@ addenv(Param pm, char *value)
pm->env = NULL; pm->env = NULL;
return; return;
} }
#ifdef HAVE_UNSETENV
/*
* 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. * Under Cygwin we must use putenv() to maintain consistency.
* Unfortunately, current version (1.1.2) copies argument and may * Unfortunately, current version (1.1.2) copies argument and may
@ -3973,6 +4021,7 @@ addenv(Param pm, char *value)
DPUTS(1, "addenv should never reach the end"); DPUTS(1, "addenv should never reach the end");
pm->env = NULL; pm->env = NULL;
#endif
} }
@ -4003,6 +4052,7 @@ mkenvstr(char *name, char *value, int flags)
* string. */ * string. */
#ifndef HAVE_UNSETENV
/**/ /**/
void void
delenvvalue(char *x) delenvvalue(char *x)
@ -4018,6 +4068,8 @@ delenvvalue(char *x)
} }
zsfree(x); zsfree(x);
} }
#endif
/* Delete a pointer from the list of pointers to environment * /* Delete a pointer from the list of pointers to environment *
* variables by shifting all the other pointers up one slot. */ * variables by shifting all the other pointers up one slot. */
@ -4026,7 +4078,12 @@ delenvvalue(char *x)
void void
delenv(Param pm) delenv(Param pm)
{ {
#ifdef HAVE_UNSETENV
unsetenv(pm->node.nam);
zsfree(pm->env);
#else
delenvvalue(pm->env); delenvvalue(pm->env);
#endif
pm->env = NULL; pm->env = NULL;
/* /*
* Note we don't remove PM_EXPORT from the flags. This * Note we don't remove PM_EXPORT from the flags. This

View File

@ -693,6 +693,15 @@ struct timezone {
extern char **environ; 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.
*/
#ifndef HAVE_UNSETENV
#undef HAVE_SETENV
#endif
/* These variables are sometimes defined in, * /* These variables are sometimes defined in, *
* and needed by, the termcap library. */ * and needed by, the termcap library. */
#if MUST_DEFINE_OSPEED #if MUST_DEFINE_OSPEED

View File

@ -1126,7 +1126,7 @@ AC_CHECK_FUNCS(strftime strptime mktime timelocal \
setlocale \ setlocale \
uname \ uname \
signgam \ signgam \
putenv getenv \ putenv getenv setenv unsetenv xw\
brk sbrk \ brk sbrk \
pathconf sysconf \ pathconf sysconf \
tgetent tigetflag tigetnum tigetstr setupterm \ tgetent tigetflag tigetnum tigetstr setupterm \