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
}