summaryrefslogtreecommitdiffstats
path: root/generic
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 /generic
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]
Diffstat (limited to 'generic')
-rw-r--r--generic/tclEnv.c34
1 files changed, 27 insertions, 7 deletions
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));