Add a multiple-reader/single-writer lock to protect environ.
This commit is contained in:
parent
03e28bdbaf
commit
4bbb5fd353
@ -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
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user