--- setenv.c.orig	Wed Feb 23 19:05:09 2005
+++ setenv.c	Wed Feb 23 19:05:09 2005
@@ -40,8 +40,13 @@
 #include <stddef.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/types.h>
 
 char *__findenv(const char *, int *);
+void *env_reallocf(void *, size_t, int);
+void env_free(void *, int);
+
+static uint8_t *dynamicEnv;
 
 /*
  * setenv --
@@ -77,24 +82,29 @@
 		if (alloced == environ) {	/* just increase size */
 			p = (char **)realloc((char *)environ,
 			    (size_t)(sizeof(char *) * (cnt + 2)));
-			if (!p)
+			dynamicEnv = (uint8_t *)realloc(dynamicEnv,
+			    (size_t)(cnt + 2));
+			if (!p || !dynamicEnv)
 				return (-1);
 			alloced = environ = p;
 		}
 		else {				/* get new space */
 						/* copy old entries into it */
 			p = malloc((size_t)(sizeof(char *) * (cnt + 2)));
-			if (!p)
+			dynamicEnv = calloc(1, (size_t)(cnt + 2));
+			if (!p || !dynamicEnv)
 				return (-1);
 			bcopy(environ, p, cnt * sizeof(char *));
 			alloced = environ = p;
 		}
 		environ[cnt + 1] = NULL;
 		offset = cnt;
+		dynamicEnv[cnt + 1] = 0;
 	}
 	for (c = (char *)name; *c && *c != '='; ++c);	/* no `=' in name */
 	if (!(environ[offset] =			/* name + `=' + value */
-	    malloc((size_t)((int)(c - name) + l_value + 2))))
+	    env_reallocf(environ[offset],
+	    (size_t)((int)(c - name) + l_value + 2), offset)))
 		return (-1);
 	for (c = environ[offset]; (*c = *name++) && *c != '='; ++c);
 	for (*c++ = '='; (*c++ = *value++); );
@@ -113,8 +123,53 @@
 	char **p;
 	int offset;
 
-	while (__findenv(name, &offset))	/* if set multiple times */
+	while (__findenv(name, &offset)) {	/* if set multiple times */
+		env_free(environ[offset], offset);
 		for (p = &environ[offset];; ++p)
 			if (!(*p = *(p + 1)))
 				break;
+	}
+}
+
+/*
+ * env_reallocf(ptr, size, offset) --
+ *	Reallocate an environment variable while tracking that it is dynamically
+ *	allocated for deallocation later.
+ */
+static void *
+env_reallocf(ptr, size, offset)
+	void *ptr;
+	size_t size;
+	int offset;
+{
+	/*
+	 * realloc() pointer if it is dynamic, otherwise, track it as dynamic
+	 * and malloc() a new memory block.
+	 */
+	if (dynamicEnv && dynamicEnv[offset]) {
+		return (reallocf(ptr, size));
+	} else {
+		dynamicEnv[offset] = 1;
+		return (malloc(size));
+	}
+}
+
+/*
+ * env_free(ptr, offset) --
+ *	Free an environment variable while removing it from the system tracking
+ *	dynamically allocated variables.
+ */
+static void
+env_free(ptr, offset)
+	void *ptr;
+	int offset;
+{
+	extern char **environ;
+	char **p;
+
+	if (dynamicEnv && dynamicEnv[offset]) {
+		for (p = &environ[offset]; *p; ++p)
+			dynamicEnv[offset] = dynamicEnv[offset + 1];
+		free(ptr);
+	}
 }

