Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/lib/libc Use a bit array to keep track of malloced environme...
details: https://anonhg.NetBSD.org/src/rev/9d9e66dc2ab4
branches: trunk
changeset: 757796:9d9e66dc2ab4
user: christos <christos%NetBSD.org@localhost>
date: Thu Sep 23 17:30:49 2010 +0000
description:
Use a bit array to keep track of malloced environment entries so we can
free them.
diffstat:
lib/libc/compat/stdlib/compat_unsetenv.c | 7 +++--
lib/libc/stdlib/getenv.c | 39 ++++++++++++++++++++++++++++---
lib/libc/stdlib/local.h | 12 ++++++++-
lib/libc/stdlib/setenv.c | 21 ++++++++++++----
lib/libc/stdlib/unsetenv.c | 28 +++++++++++++---------
5 files changed, 81 insertions(+), 26 deletions(-)
diffs (251 lines):
diff -r 9ab7b9b99c50 -r 9d9e66dc2ab4 lib/libc/compat/stdlib/compat_unsetenv.c
--- a/lib/libc/compat/stdlib/compat_unsetenv.c Thu Sep 23 16:02:41 2010 +0000
+++ b/lib/libc/compat/stdlib/compat_unsetenv.c Thu Sep 23 17:30:49 2010 +0000
@@ -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 <bitstring.h>
+#include "reentrant.h"
#include "local.h"
-#include "reentrant.h"
#ifdef __weak_alias
__weak_alias(unsetenv,_unsetenv)
diff -r 9ab7b9b99c50 -r 9d9e66dc2ab4 lib/libc/stdlib/getenv.c
--- a/lib/libc/stdlib/getenv.c Thu Sep 23 16:02:41 2010 +0000
+++ b/lib/libc/stdlib/getenv.c Thu Sep 23 17:30:49 2010 +0000
@@ -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 <bitstring.h>
+#include "reentrant.h"
#include "local.h"
-#include "reentrant.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.
diff -r 9ab7b9b99c50 -r 9d9e66dc2ab4 lib/libc/stdlib/local.h
--- a/lib/libc/stdlib/local.h Thu Sep 23 16:02:41 2010 +0000
+++ b/lib/libc/stdlib/local.h Thu Sep 23 17:30:49 2010 +0000
@@ -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;
diff -r 9ab7b9b99c50 -r 9d9e66dc2ab4 lib/libc/stdlib/setenv.c
--- a/lib/libc/stdlib/setenv.c Thu Sep 23 16:02:41 2010 +0000
+++ b/lib/libc/stdlib/setenv.c Thu Sep 23 17:30:49 2010 +0000
@@ -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 <bitstring.h>
+#include "reentrant.h"
#include "local.h"
-#include "reentrant.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:
diff -r 9ab7b9b99c50 -r 9d9e66dc2ab4 lib/libc/stdlib/unsetenv.c
--- a/lib/libc/stdlib/unsetenv.c Thu Sep 23 16:02:41 2010 +0000
+++ b/lib/libc/stdlib/unsetenv.c Thu Sep 23 17:30:49 2010 +0000
@@ -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;
Home |
Main Index |
Thread Index |
Old Index