diff options
| author | kleink <kleink@NetBSD.org> | 1998-09-11 21:03:18 +0000 |
|---|---|---|
| committer | kleink <kleink@NetBSD.org> | 1998-09-11 21:03:18 +0000 |
| commit | 4bbb5fd353e9c023c4c01f839471ee763529c839 (patch) | |
| tree | 1b7db0164d54daba827811f880202cc2481dd31a /lib/libc/stdlib | |
| parent | 03e28bdbafa8ffc753532f225238db3e501f2152 (diff) | |
Add a multiple-reader/single-writer lock to protect environ.
Diffstat (limited to 'lib/libc/stdlib')
| -rw-r--r-- | lib/libc/stdlib/getenv.c | 15 | ||||
| -rw-r--r-- | lib/libc/stdlib/setenv.c | 30 |
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); } |
