Tcl Source Code

Artifact [1afe267e29]
Login

Artifact 1afe267e2969489659e144e3a440b3e7c9d01efb:

Attachment "env.patch2" to ticket [653511ffff] added by mdejong 2003-02-19 03:05:36.
2002-12-13  Mo DeJong  <[email protected]>

	* generic/tclEnv.c (TclFinalizeEnvironment): Deallocate
	all the memory we allocated when not using putenv. Also
	reset the original environ pointer.

Index: generic/tclEnv.c
===================================================================
RCS file: /cvsroot/tcl/tcl/generic/tclEnv.c,v
retrieving revision 1.19
diff -u -r1.19 tclEnv.c
--- generic/tclEnv.c	14 Oct 2002 22:25:10 -0000	1.19
+++ generic/tclEnv.c	13 Dec 2002 23:13:34 -0000
@@ -26,11 +26,14 @@
 				 * strings that Tcl has allocated. */
 
 #ifndef USE_PUTENV
-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
-				 * once).  Zero means that the environment
-				 * array is in its original static state. */
+static char **originalEnviron = NULL;
+				/* Pointer to initial environment. Non-NULL
+				 * means that the environ array was ckalloced.
+				 * A NULL originalEnviron means that the
+				 * environment is in its original state. */
+static int environSize = 0;	/* The environ array has this many total
+				 * entries allocated to it (not all may
+				 * be in use at once). */
 #endif
 
 /*
@@ -198,9 +201,11 @@
 		    ((length + 5) * sizeof(char *)));
 	    memcpy((VOID *) newEnviron, (VOID *) environ,
 		    length*sizeof(char *));
-	    if (environSize != 0) {
+	    if (originalEnviron == NULL) {
+                originalEnviron = environ;
+	    } else {
 		ckfree((char *) environ);
-	    }
+            }
 	    environ = newEnviron;
 	    environSize = length + 5;
 #if defined(__APPLE__) && defined(__DYNAMIC__)
@@ -681,18 +686,30 @@
 TclFinalizeEnvironment()
 {
     /*
-     * For now we just deallocate the cache array and none of the environment
-     * strings.  This may leak more memory that strictly necessary, since some
-     * of the strings may no longer be in the environment.  However,
-     * determining which ones are ok to delete is n-squared, and is pretty
-     * unlikely, so we don't bother.
+     * If we are not using putenv, then we can deallocate the
+     * env entries we allocated (they are in the cache) and
+     * reset the original environ pointer. If we are using
+     * putenv then we leak the memory for each env var
+     * that is set in order to avoid a n-squared search
+     * for the pointers that we wanted to delete.
      */
 
     if (environCache) {
+#ifndef USE_PUTENV
+	int i;
+	for (i = 0; i < cacheSize && environCache[i] ; i++) {
+	    ckfree(environCache[i]);
+	}
+#endif
 	ckfree((char *) environCache);
 	environCache = NULL;
 	cacheSize    = 0;
 #ifndef USE_PUTENV
+        if (originalEnviron != NULL) {
+            ckfree((char *) environ);
+            environ = originalEnviron;
+            originalEnviron = NULL;
+        }
 	environSize  = 0;
 #endif
     }