Add a multiple-reader/single-writer lock to protect environ.

This commit is contained in:
kleink 1998-09-11 21:03:18 +00:00
parent 03e28bdbaf
commit 4bbb5fd353
5 changed files with 74 additions and 19 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: execl.c,v 1.5 1997/11/20 01:26:45 mjacob Exp $ */
/* $NetBSD: execl.c,v 1.6 1998/09/11 21:03:18 kleink Exp $ */
/*-
* Copyright (c) 1991, 1993
@ -38,13 +38,14 @@
#if 0
static char sccsid[] = "@(#)exec.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: execl.c,v 1.5 1997/11/20 01:26:45 mjacob Exp $");
__RCSID("$NetBSD: execl.c,v 1.6 1998/09/11 21:03:18 kleink Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
#include "namespace.h"
#include <stdlib.h>
#include <unistd.h>
#include "reentrant.h"
#if __STDC__
#include <stdarg.h>
@ -60,6 +61,9 @@ __weak_alias(execl,_execl);
extern char **environ;
#ifdef _REENT
extern rwlock_t __environ_lock;
#endif
int
#if __STDC__
@ -71,8 +75,12 @@ execl(name, arg, va_alist)
va_dcl
#endif
{
int r;
#if defined(__i386__) || defined(__m68k__) || defined(__ns32k__)
return execve(name, (char **) &arg, environ);
rwlock_rdlock(&__environ_lock);
r = execve(name, (char **) &arg, environ);
rwlock_unlock(&__environ_lock);
return (r);
#else
va_list ap;
char **argv;
@ -91,6 +99,9 @@ execl(name, arg, va_alist)
;
va_end(ap);
return execve(name, argv, environ);
rwlock_rdlock(&__environ_lock);
r = execve(name, argv, environ);
rwlock_unlock(&__environ_lock);
return (r);
#endif
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: execv.c,v 1.3 1997/07/21 14:06:56 jtc Exp $ */
/* $NetBSD: execv.c,v 1.4 1998/09/11 21:03:18 kleink Exp $ */
/*-
* Copyright (c) 1991, 1993
@ -38,23 +38,32 @@
#if 0
static char sccsid[] = "@(#)exec.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: execv.c,v 1.3 1997/07/21 14:06:56 jtc Exp $");
__RCSID("$NetBSD: execv.c,v 1.4 1998/09/11 21:03:18 kleink Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
#include "namespace.h"
#include <unistd.h>
#include "reentrant.h"
#ifdef __weak_alias
__weak_alias(execv,_execv);
#endif
extern char **environ;
#ifdef _REENT
extern rwlock_t __environ_lock;
#endif
int
execv(name, argv)
const char *name;
char * const *argv;
{
return execve(name, argv, environ);
int r;
rwlock_rdlock(&__environ_lock);
r = execve(name, argv, environ);
rwlock_unlock(&__environ_lock);
return (r);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: execvp.c,v 1.8 1998/08/26 00:38:39 perry Exp $ */
/* $NetBSD: execvp.c,v 1.9 1998/09/11 21:03:18 kleink Exp $ */
/*-
* Copyright (c) 1991, 1993
@ -38,7 +38,7 @@
#if 0
static char sccsid[] = "@(#)exec.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: execvp.c,v 1.8 1998/08/26 00:38:39 perry Exp $");
__RCSID("$NetBSD: execvp.c,v 1.9 1998/09/11 21:03:18 kleink Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@ -50,12 +50,16 @@ __RCSID("$NetBSD: execvp.c,v 1.8 1998/08/26 00:38:39 perry Exp $");
#include <limits.h>
#include <unistd.h>
#include <paths.h>
#include "reentrant.h"
#ifdef __weak_alias
__weak_alias(execvp,_execvp);
#endif
extern char **environ;
#ifdef _REENT
extern rwlock_t __environ_lock;
#endif
int
execvp(name, argv)
@ -118,7 +122,9 @@ execvp(name, argv)
memmove(buf + lp + 1, name, ln);
buf[lp + ln + 1] = '\0';
retry: (void)execve(bp, argv, environ);
retry: rwlock_rdlock(&__environ_lock);
(void)execve(bp, argv, environ);
rwlock_unlock(&__environ_lock);
switch(errno) {
case EACCES:
eacces = 1;
@ -137,7 +143,9 @@ retry: (void)execve(bp, argv, environ);
memp[0] = "sh";
memp[1] = bp;
memmove(memp + 2, argv + 1, cnt * sizeof(char *));
rwlock_rdlock(&__environ_lock);
(void)execve(_PATH_BSHELL, memp, environ);
rwlock_unlock(&__environ_lock);
goto done;
case ETXTBSY:
if (etxtbsy < 3)

View File

@ -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);
}
/*

View File

@ -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);
}