summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog11
-rw-r--r--generic/tclEnv.c45
-rw-r--r--win/tclWinPort.h5
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 <jeffh@ActiveState.com>
+
+ * 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 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.