summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhobbs <hobbs>2005-10-05 08:03:35 (GMT)
committerhobbs <hobbs>2005-10-05 08:03:35 (GMT)
commit44e8c0a01c0a4104585a07493094db8366e7ccc8 (patch)
tree5bde422719d3a328094434e639f02b3dc73a6223
parenta7c1a3d607d3f3a9645ac43c6de183e49693111a (diff)
downloadtcl-44e8c0a01c0a4104585a07493094db8366e7ccc8.zip
tcl-44e8c0a01c0a4104585a07493094db8366e7ccc8.tar.gz
tcl-44e8c0a01c0a4104585a07493094db8366e7ccc8.tar.bz2
* 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]
-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.