summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog12
-rw-r--r--generic/tclEnv.c34
-rw-r--r--tests/env.test9
-rw-r--r--win/tclWinPort.h5
4 files changed, 50 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog
index e1b5894..866e14d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.