summaryrefslogtreecommitdiff
path: root/lib/libc/stdlib
diff options
context:
space:
mode:
authorkleink <kleink@NetBSD.org>1998-09-11 21:03:18 +0000
committerkleink <kleink@NetBSD.org>1998-09-11 21:03:18 +0000
commit4bbb5fd353e9c023c4c01f839471ee763529c839 (patch)
tree1b7db0164d54daba827811f880202cc2481dd31a /lib/libc/stdlib
parent03e28bdbafa8ffc753532f225238db3e501f2152 (diff)
Add a multiple-reader/single-writer lock to protect environ.
Diffstat (limited to 'lib/libc/stdlib')
-rw-r--r--lib/libc/stdlib/getenv.c15
-rw-r--r--lib/libc/stdlib/setenv.c30
2 files changed, 36 insertions, 9 deletions
diff --git a/lib/libc/stdlib/getenv.c b/lib/libc/stdlib/getenv.c
index 70e38a830a7..d819b0f13ed 100644
--- a/lib/libc/stdlib/getenv.c
+++ b/lib/libc/stdlib/getenv.c
@@ -1,4 +1,4 @@
-/* $NetBSD: getenv.c,v 1.10 1998/02/03 18:44:15 perry Exp $ */
+/* $NetBSD: getenv.c,v 1.11 1998/09/11 21:03:18 kleink Exp $ */
/*
* Copyright (c) 1987, 1993
@@ -38,13 +38,18 @@
#if 0
static char sccsid[] = "@(#)getenv.c 8.1 (Berkeley) 6/4/93";
#else
-__RCSID("$NetBSD: getenv.c,v 1.10 1998/02/03 18:44:15 perry Exp $");
+__RCSID("$NetBSD: getenv.c,v 1.11 1998/09/11 21:03:18 kleink Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
#include <stdlib.h>
#include <string.h>
#include "local.h"
+#include "reentrant.h"
+
+#ifdef _REENT
+rwlock_t __environ_lock = RWLOCK_INITIALIZER;
+#endif
/*
* getenv --
@@ -55,8 +60,12 @@ getenv(name)
const char *name;
{
int offset;
+ char *result;
- return (__findenv(name, &offset));
+ rwlock_rdlock(&__environ_lock);
+ result = __findenv(name, &offset);
+ rwlock_unlock(&__environ_lock);
+ return (result);
}
/*
diff --git a/lib/libc/stdlib/setenv.c b/lib/libc/stdlib/setenv.c
index 4d11f04d80c..78da4b32f8e 100644
--- a/lib/libc/stdlib/setenv.c
+++ b/lib/libc/stdlib/setenv.c
@@ -1,4 +1,4 @@
-/* $NetBSD: setenv.c,v 1.13 1998/08/10 02:43:10 perry Exp $ */
+/* $NetBSD: setenv.c,v 1.14 1998/09/11 21:03:18 kleink Exp $ */
/*
* Copyright (c) 1987, 1993
@@ -38,7 +38,7 @@
#if 0
static char sccsid[] = "@(#)setenv.c 8.1 (Berkeley) 6/4/93";
#else
-__RCSID("$NetBSD: setenv.c,v 1.13 1998/08/10 02:43:10 perry Exp $");
+__RCSID("$NetBSD: setenv.c,v 1.14 1998/09/11 21:03:18 kleink Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@@ -46,12 +46,17 @@ __RCSID("$NetBSD: setenv.c,v 1.13 1998/08/10 02:43:10 perry Exp $");
#include <stdlib.h>
#include <string.h>
#include "local.h"
+#include "reentrant.h"
#ifdef __weak_alias
__weak_alias(setenv,_setenv);
__weak_alias(unsetenv,_unsetenv);
#endif
+#ifdef _REENT
+extern rwlock_t __environ_lock;
+#endif
+
/*
* setenv --
* Set the value of the environmental variable "name" to be
@@ -71,11 +76,15 @@ setenv(name, value, rewrite)
if (*value == '=') /* no `=' in value */
++value;
l_value = strlen(value);
+ rwlock_wrlock(&__environ_lock);
if ((c = __findenv(name, &offset))) { /* find if already exists */
- if (!rewrite)
+ if (!rewrite) {
+ rwlock_unlock(&__environ_lock);
return (0);
+ }
if (strlen(c) >= l_value) { /* old larger; copy over */
while ((*c++ = *value++) != '\0');
+ rwlock_unlock(&__environ_lock);
return (0);
}
} else { /* create new slot */
@@ -86,14 +95,18 @@ setenv(name, value, rewrite)
if (alloced) { /* just increase size */
environ = (char **)realloc((char *)environ,
(size_t)(sizeof(char *) * (cnt + 2)));
- if (!environ)
+ if (!environ) {
+ rwlock_unlock(&__environ_lock);
return (-1);
+ }
}
else { /* get new space */
alloced = 1; /* copy old entries into it */
p = malloc((size_t)(sizeof(char *) * (cnt + 2)));
- if (!p)
+ if (!p) {
+ rwlock_unlock(&__environ_lock);
return (-1);
+ }
memcpy(p, environ, cnt * sizeof(char *));
environ = p;
}
@@ -102,10 +115,13 @@ setenv(name, value, rewrite)
}
for (c = (char *)name; *c && *c != '='; ++c); /* no `=' in name */
if (!(environ[offset] = /* name + `=' + value */
- malloc((size_t)((int)(c - name) + l_value + 2))))
+ malloc((size_t)((int)(c - name) + l_value + 2)))) {
+ rwlock_unlock(&__environ_lock);
return (-1);
+ }
for (c = environ[offset]; (*c = *name++) && *c != '='; ++c);
for (*c++ = '='; (*c++ = *value++) != '\0'; );
+ rwlock_unlock(&__environ_lock);
return (0);
}
@@ -121,8 +137,10 @@ unsetenv(name)
char **p;
int offset;
+ rwlock_wrlock(&__environ_lock);
while (__findenv(name, &offset)) /* if set multiple times */
for (p = &environ[offset];; ++p)
if (!(*p = *(p + 1)))
break;
+ rwlock_unlock(&__environ_lock);
}