From 244bc931a8bd5bd2daf06b45906027f9035a5943 Mon Sep 17 00:00:00 2001 From: hobbs Date: Wed, 5 Oct 2005 08:02:19 +0000 Subject: * 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] --- ChangeLog | 11 +++++++++++ generic/tclEnv.c | 45 ++++++++++++++++++++++++++++++++------------- win/tclWinPort.h | 5 +++-- 3 files changed, 46 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8693f38..b555297 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2005-10-05 Jeff Hobbs + + * 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 * win/tclWinSerial.c (SerialSetOptionProc): free argv [Bug 1067708] diff --git a/generic/tclEnv.c b/generic/tclEnv.c index 1e171ff..947d397 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.20.2.1 2003/05/14 17:17:46 hobbs Exp $ + * RCS: @(#) $Id: tclEnv.c,v 1.20.2.2 2005/10/05 08:02:20 hobbs Exp $ */ #include "tclInt.h" @@ -26,6 +26,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 @@ -191,17 +196,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__) { @@ -237,7 +247,6 @@ TclSetEnv(name, value) oldValue = environ[index]; nameLength = length; } - /* * Create a new entry. Build a complete UTF string that contains @@ -378,7 +387,7 @@ TclUnsetEnv(name) char *oldValue; int length; int index; -#ifdef USE_PUTENV +#ifdef USE_PUTENV_FOR_UNSET Tcl_DString envString; char *string; #else @@ -392,7 +401,7 @@ TclUnsetEnv(name) * First make sure that the environment variable exists to avoid * doing needless work and to avoid recursion on the unset. */ - + if (index == -1) { Tcl_MutexUnlock(&envMutex); return; @@ -408,12 +417,22 @@ TclUnsetEnv(name) * update the 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)); strcpy(string, Tcl_DStringValue(&envString)); @@ -633,7 +652,7 @@ ReplaceString(oldStr, newStr) if (environCache[i]) { ckfree(environCache[i]); } - + if (newStr) { environCache[i] = newStr; } else { @@ -642,7 +661,7 @@ ReplaceString(oldStr, newStr) } environCache[cacheSize-1] = NULL; } - } else { + } else { int allocatedSize = (cacheSize + 5) * sizeof(char *); /* @@ -651,7 +670,7 @@ ReplaceString(oldStr, newStr) newCache = (char **) ckalloc((unsigned) allocatedSize); (VOID *) memset(newCache, (int) 0, (size_t) allocatedSize); - + if (environCache) { memcpy((VOID *) newCache, (VOID *) environCache, (size_t) (cacheSize * sizeof(char*))); diff --git a/win/tclWinPort.h b/win/tclWinPort.h index c553ea6..47545ba 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.36 2002/11/27 18:13:38 davygrvy Exp $ + * RCS: @(#) $Id: tclWinPort.h,v 1.36.2.1 2005/10/05 08:02:20 hobbs Exp $ */ #ifndef _TCLWINPORT @@ -423,7 +423,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. -- cgit v0.12