diff options
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | generic/tclEnv.c | 34 | ||||
-rw-r--r-- | tests/env.test | 9 | ||||
-rw-r--r-- | win/tclWinPort.h | 5 |
4 files changed, 50 insertions, 10 deletions
@@ -1,3 +1,15 @@ +2005-10-05 Jeff Hobbs <jeffh@ActiveState.com> + + * tests/env.test (env-6.1): + * win/tclWinPort.h: define USE_PUTENV_FOR_UNSET 1 + * generic/tclEnv.c (TclSetEnv, TclUnsetEnv): add + USE_PUTENV_FOR_UNSET to existing USE_PUTENV define to account for + various systems that have putenv(), but can't unset env vars with + it. Note difference between Windows and Linux for actually + unsetting the env var (use of '='). + Correct the resizing of the environ array. We assume that we are + in full ownership, but that's not correct.[Bug 979640] + 2005-10-04 Jeff Hobbs <jeffh@ActiveState.com> * win/tclWinSerial.c (SerialSetOptionProc): free argv [Bug 1067708] diff --git a/generic/tclEnv.c b/generic/tclEnv.c index 287a3a8..2aa927b 100644 --- a/generic/tclEnv.c +++ b/generic/tclEnv.c @@ -12,7 +12,7 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclEnv.c,v 1.25 2005/07/21 14:38:31 dkf Exp $ + * RCS: @(#) $Id: tclEnv.c,v 1.26 2005/10/05 08:03:35 hobbs Exp $ */ #include "tclInt.h" @@ -25,6 +25,11 @@ static char **environCache = NULL; * strings that Tcl has allocated. */ #ifndef USE_PUTENV +static char **ourEnviron = NULL;/* Cache of the array that we allocate. + * We need to track this in case another + * subsystem swaps around the environ array + * like we do. + */ static int environSize = 0; /* Non-zero means that the environ array was * malloced and has this many total entries * allocated to it (not all may be in use at @@ -189,17 +194,22 @@ TclSetEnv(name, value) if (index == -1) { #ifndef USE_PUTENV - if ((length + 2) > environSize) { + /* + * We need to handle the case where the environment may be changed + * outside our control. environSize is only valid if the current + * environment is the one we allocated. [Bug 979640] + */ + if ((ourEnviron != environ) || ((length + 2) > environSize)) { char **newEnviron; newEnviron = (char **) ckalloc((unsigned) ((length + 5) * sizeof(char *))); memcpy((VOID *) newEnviron, (VOID *) environ, length*sizeof(char *)); - if (environSize != 0) { - ckfree((char *) environ); + if ((environSize != 0) && (ourEnviron != NULL)) { + ckfree((char *) ourEnviron); } - environ = newEnviron; + environ = ourEnviron = newEnviron; environSize = length + 5; #if defined(__APPLE__) && defined(__DYNAMIC__) { @@ -375,7 +385,7 @@ TclUnsetEnv(name) char *oldValue; int length; int index; -#ifdef USE_PUTENV +#ifdef USE_PUTENV_FOR_UNSET Tcl_DString envString; char *string; #else @@ -405,11 +415,21 @@ TclUnsetEnv(name) * interpreters or we will recurse. */ -#ifdef USE_PUTENV +#ifdef USE_PUTENV_FOR_UNSET + /* + * For those platforms that support putenv to unset, Linux indicates + * that no = should be included, and Windows requires it. + */ +#ifdef WIN32 string = ckalloc((unsigned int) length+2); memcpy((VOID *) string, (VOID *) name, (size_t) length); string[length] = '='; string[length+1] = '\0'; +#else + string = ckalloc((unsigned int) length+1); + memcpy((VOID *) string, (VOID *) name, (size_t) length); + string[length] = '\0'; +#endif Tcl_UtfToExternalDString(NULL, string, -1, &envString); string = ckrealloc(string, (unsigned) (Tcl_DStringLength(&envString)+1)); diff --git a/tests/env.test b/tests/env.test index 24dc2e3..c2bad61 100644 --- a/tests/env.test +++ b/tests/env.test @@ -11,7 +11,7 @@ # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. # -# RCS: @(#) $Id: env.test,v 1.21 2005/05/24 04:44:08 das Exp $ +# RCS: @(#) $Id: env.test,v 1.22 2005/10/05 08:03:35 hobbs Exp $ if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest 2 @@ -232,6 +232,13 @@ test env-5.5 {corner cases - cannot have null entries on Windows} {win} { catch {set env()} } {1} +test env-6.1 {corner cases - add lots of env variables} {} { + set size [array size env] + for {set i 0} {$i < 100} {incr i} { + set env(BOGUS$i) $i + } + expr {[array size env] - $size} +} 100 # Restore the environment variables at the end of the test. diff --git a/win/tclWinPort.h b/win/tclWinPort.h index 1263e12..4c11208 100644 --- a/win/tclWinPort.h +++ b/win/tclWinPort.h @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tclWinPort.h,v 1.44 2005/06/01 11:00:36 dkf Exp $ + * RCS: @(#) $Id: tclWinPort.h,v 1.45 2005/10/05 08:03:35 hobbs Exp $ */ #ifndef _TCLWINPORT @@ -445,7 +445,8 @@ * the C level environment in synch with the system level environment. */ -#define USE_PUTENV 1 +#define USE_PUTENV 1 +#define USE_PUTENV_FOR_UNSET 1 /* * Msvcrt's putenv() copies the string rather than takes ownership of it. |