Module Name:    src
Committed By:   christos
Date:           Thu Sep 23 17:30:49 UTC 2010

Modified Files:
        src/lib/libc/compat/stdlib: compat_unsetenv.c
        src/lib/libc/stdlib: getenv.c local.h setenv.c unsetenv.c

Log Message:
Use a bit array to keep track of malloced environment entries so we can
free them.


To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 src/lib/libc/compat/stdlib/compat_unsetenv.c
cvs rdiff -u -r1.19 -r1.20 src/lib/libc/stdlib/getenv.c
cvs rdiff -u -r1.2 -r1.3 src/lib/libc/stdlib/local.h
cvs rdiff -u -r1.33 -r1.34 src/lib/libc/stdlib/setenv.c
cvs rdiff -u -r1.3 -r1.4 src/lib/libc/stdlib/unsetenv.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libc/compat/stdlib/compat_unsetenv.c
diff -u src/lib/libc/compat/stdlib/compat_unsetenv.c:1.1 src/lib/libc/compat/stdlib/compat_unsetenv.c:1.2
--- src/lib/libc/compat/stdlib/compat_unsetenv.c:1.1	Mon Sep 12 21:44:09 2005
+++ src/lib/libc/compat/stdlib/compat_unsetenv.c	Thu Sep 23 13:30:49 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: compat_unsetenv.c,v 1.1 2005/09/13 01:44:09 christos Exp $	*/
+/*	$NetBSD: compat_unsetenv.c,v 1.2 2010/09/23 17:30:49 christos Exp $	*/
 
 /*
  * Copyright (c) 1987, 1993
@@ -34,7 +34,7 @@
 #if 0
 static char sccsid[] = "from: @(#)setenv.c	8.1 (Berkeley) 6/4/93";
 #else
-__RCSID("$NetBSD: compat_unsetenv.c,v 1.1 2005/09/13 01:44:09 christos Exp $");
+__RCSID("$NetBSD: compat_unsetenv.c,v 1.2 2010/09/23 17:30:49 christos Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -46,8 +46,9 @@
 #include <stdlib.h>
 #include <compat/include/stdlib.h>
 #include <string.h>
-#include "local.h"
+#include <bitstring.h>
 #include "reentrant.h"
+#include "local.h"
 
 #ifdef __weak_alias
 __weak_alias(unsetenv,_unsetenv)

Index: src/lib/libc/stdlib/getenv.c
diff -u src/lib/libc/stdlib/getenv.c:1.19 src/lib/libc/stdlib/getenv.c:1.20
--- src/lib/libc/stdlib/getenv.c:1.19	Fri Oct 31 13:46:04 2008
+++ src/lib/libc/stdlib/getenv.c	Thu Sep 23 13:30:49 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: getenv.c,v 1.19 2008/10/31 17:46:04 christos Exp $	*/
+/*	$NetBSD: getenv.c,v 1.20 2010/09/23 17:30:49 christos Exp $	*/
 
 /*
  * Copyright (c) 1987, 1993
@@ -34,7 +34,7 @@
 #if 0
 static char sccsid[] = "@(#)getenv.c	8.1 (Berkeley) 6/4/93";
 #else
-__RCSID("$NetBSD: getenv.c,v 1.19 2008/10/31 17:46:04 christos Exp $");
+__RCSID("$NetBSD: getenv.c,v 1.20 2010/09/23 17:30:49 christos Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -43,13 +43,15 @@
 #include <errno.h>
 #include <stdlib.h>
 #include <string.h>
-#include "local.h"
+#include <bitstring.h>
 #include "reentrant.h"
+#include "local.h"
 
 #ifdef _REENTRANT
 rwlock_t __environ_lock = RWLOCK_INITIALIZER;
 #endif
-extern char **environ;
+bitstr_t *__environ_malloced;
+static size_t environ_bitlen;
 
 __weak_alias(getenv_r, _getenv_r)
 
@@ -99,6 +101,35 @@
 	return rv;
 }
 
+int
+__allocenv(int offset)
+{
+	bitstr_t *s;
+	size_t nl;
+
+	if (offset == -1) {
+		char **ptr;
+		for (ptr = environ, offset = 0; *ptr; ptr++)
+			offset++;
+	}
+	nl = bitstr_size(offset + 2);
+	if (__environ_malloced == NULL) {
+		s = malloc(nl);
+	} else if (environ_bitlen < nl)
+		s = realloc(__environ_malloced, nl);
+	else
+		return 0;
+
+	if (s == NULL)
+		return -1;
+
+	(void)memset(&s[environ_bitlen], 0, nl - environ_bitlen);
+	environ_bitlen = nl;
+	__environ_malloced = s;
+
+	return 0;
+}
+
 /*
  * __findenv --
  *	Returns pointer to value associated with name, if any, else NULL.

Index: src/lib/libc/stdlib/local.h
diff -u src/lib/libc/stdlib/local.h:1.2 src/lib/libc/stdlib/local.h:1.3
--- src/lib/libc/stdlib/local.h:1.2	Tue Oct 20 21:07:45 2009
+++ src/lib/libc/stdlib/local.h	Thu Sep 23 13:30:49 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: local.h,v 1.2 2009/10/21 01:07:45 snj Exp $	*/
+/*	$NetBSD: local.h,v 1.3 2010/09/23 17:30:49 christos Exp $	*/
 
 /*
  * Copyright (c) 1997 Christos Zoulas.  All rights reserved.
@@ -24,4 +24,12 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-char *__findenv __P((const char *, int *));
+char *__findenv(const char *, int *);
+int __allocenv(int);
+
+#ifdef _REENTRANT
+extern rwlock_t __environ_lock;
+#endif
+
+extern char **environ;
+extern bitstr_t *__environ_malloced;

Index: src/lib/libc/stdlib/setenv.c
diff -u src/lib/libc/stdlib/setenv.c:1.33 src/lib/libc/stdlib/setenv.c:1.34
--- src/lib/libc/stdlib/setenv.c:1.33	Thu Sep 23 12:02:41 2010
+++ src/lib/libc/stdlib/setenv.c	Thu Sep 23 13:30:49 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: setenv.c,v 1.33 2010/09/23 16:02:41 christos Exp $	*/
+/*	$NetBSD: setenv.c,v 1.34 2010/09/23 17:30:49 christos Exp $	*/
 
 /*
  * Copyright (c) 1987, 1993
@@ -34,7 +34,7 @@
 #if 0
 static char sccsid[] = "@(#)setenv.c	8.1 (Berkeley) 6/4/93";
 #else
-__RCSID("$NetBSD: setenv.c,v 1.33 2010/09/23 16:02:41 christos Exp $");
+__RCSID("$NetBSD: setenv.c,v 1.34 2010/09/23 17:30:49 christos Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -44,8 +44,9 @@
 #include <errno.h>
 #include <stdlib.h>
 #include <string.h>
-#include "local.h"
+#include <bitstring.h>
 #include "reentrant.h"
+#include "local.h"
 
 #ifdef __weak_alias
 __weak_alias(setenv,_setenv)
@@ -56,6 +57,7 @@
 #endif
 
 extern char **environ;
+extern bitstr_t *__environ_malloced;
 
 /*
  * setenv --
@@ -74,12 +76,18 @@
 	_DIAGASSERT(name != NULL);
 	_DIAGASSERT(value != NULL);
 
+	rwlock_wrlock(&__environ_lock);
+	/* find if already exists */
+	c = __findenv(name, &offset);
+
+	if (__allocenv(offset) == -1)
+		return -1;
+
 	if (*value == '=')			/* no `=' in value */
 		++value;
 	l_value = strlen(value);
-	rwlock_wrlock(&__environ_lock);
-	/* find if already exists */
-	if ((c = __findenv(name, &offset)) != NULL) {
+
+	if (c != NULL) {
 		if (!rewrite)
 			goto good;
 		if (strlen(c) > l_value)	/* old larger; copy over */
@@ -109,6 +117,7 @@
 	(void)memcpy(c, name, size);
 	c += size;
 	*c++ = '=';
+	bit_set(__environ_malloced, offset);
 copy:
 	(void)memcpy(c, value, l_value + 1);
 good:

Index: src/lib/libc/stdlib/unsetenv.c
diff -u src/lib/libc/stdlib/unsetenv.c:1.3 src/lib/libc/stdlib/unsetenv.c:1.4
--- src/lib/libc/stdlib/unsetenv.c:1.3	Mon Sep 12 21:44:10 2005
+++ src/lib/libc/stdlib/unsetenv.c	Thu Sep 23 13:30:49 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: unsetenv.c,v 1.3 2005/09/13 01:44:10 christos Exp $	*/
+/*	$NetBSD: unsetenv.c,v 1.4 2010/09/23 17:30:49 christos Exp $	*/
 
 /*
  * Copyright (c) 1987, 1993
@@ -34,7 +34,7 @@
 #if 0
 static char sccsid[] = "from: @(#)setenv.c	8.1 (Berkeley) 6/4/93";
 #else
-__RCSID("$NetBSD: unsetenv.c,v 1.3 2005/09/13 01:44:10 christos Exp $");
+__RCSID("$NetBSD: unsetenv.c,v 1.4 2010/09/23 17:30:49 christos Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -44,14 +44,9 @@
 #include <errno.h>
 #include <stdlib.h>
 #include <string.h>
-#include "local.h"
+#include <bitstring.h>
 #include "reentrant.h"
-
-#ifdef _REENTRANT
-extern rwlock_t __environ_lock;
-#endif
-
-extern char **environ;
+#include "local.h"
 
 /*
  * unsetenv(name) --
@@ -71,11 +66,22 @@
 		return -1;
 	}
 
+	if (__allocenv(-1) == -1)
+		return -1;
+
 	rwlock_wrlock(&__environ_lock);
-	while (__findenv(name, &offset))	/* if set multiple times */
-		for (p = &environ[offset];; ++p)
+	while (__findenv(name, &offset)) {	/* if set multiple times */
+		if (bit_test(__environ_malloced, offset))
+			free(environ[offset]);
+		for (p = &environ[offset];; ++p, ++offset) {
+			if (bit_test(__environ_malloced, offset + 1))
+				bit_set(__environ_malloced, offset);
+			else
+				bit_clear(__environ_malloced, offset);
 			if (!(*p = *(p + 1)))
 				break;
+		}
+	}
 	rwlock_unlock(&__environ_lock);
 
 	return 0;

Reply via email to