summaryrefslogtreecommitdiffstats
path: root/generic/tclEnv.c
diff options
context:
space:
mode:
authorhobbs <hobbs>2005-10-05 08:02:19 (GMT)
committerhobbs <hobbs>2005-10-05 08:02:19 (GMT)
commit244bc931a8bd5bd2daf06b45906027f9035a5943 (patch)
treec1c8c1ac1b39ca562df88127c192f664a293833d /generic/tclEnv.c
parent001484010656fc7ed52edb2c9a770f18cc7e6dc3 (diff)
downloadtcl-244bc931a8bd5bd2daf06b45906027f9035a5943.zip
tcl-244bc931a8bd5bd2daf06b45906027f9035a5943.tar.gz
tcl-244bc931a8bd5bd2daf06b45906027f9035a5943.tar.bz2
* 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/tclEnv.c')
-rw-r--r--generic/tclEnv.c45
1 files changed, 32 insertions, 13 deletions
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*)));