diff options
| author | nathanw <nathanw@NetBSD.org> | 2003-03-04 19:44:09 +0000 |
|---|---|---|
| committer | nathanw <nathanw@NetBSD.org> | 2003-03-04 19:44:09 +0000 |
| commit | f60f35f3abdd92d76d383ac4dd83273d2be1225b (patch) | |
| tree | c6b9b847006379eb901818b8c74701ca2029761c /lib/libc/stdlib | |
| parent | 2ea5d53fe34798182fe2bd28c6f3d0af48bd63a3 (diff) | |
Don't acquire __environ_lock around exec*() calls; nothing requires
that these calls be thread-safe with respect to the environment, and it
causes serious problems for threaded applications which call vfork() and
exec*() (including indirectly, via popen() or system()).
Acquire and release __environ_lock in the parent in popen() and system() to
play safe and provide the child with a stable environment.
__environ_lock should also have an atfork() handler; still under development.
Diffstat (limited to 'lib/libc/stdlib')
| -rw-r--r-- | lib/libc/stdlib/system.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/lib/libc/stdlib/system.c b/lib/libc/stdlib/system.c index 26179d0adb8..fb78c87cd9e 100644 --- a/lib/libc/stdlib/system.c +++ b/lib/libc/stdlib/system.c @@ -1,4 +1,4 @@ -/* $NetBSD: system.c,v 1.17 2001/10/31 13:31:26 kleink Exp $ */ +/* $NetBSD: system.c,v 1.18 2003/03/04 19:44:10 nathanw Exp $ */ /* * Copyright (c) 1988, 1993 @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)system.c 8.1 (Berkeley) 6/4/93"; #else -__RCSID("$NetBSD: system.c,v 1.17 2001/10/31 13:31:26 kleink Exp $"); +__RCSID("$NetBSD: system.c,v 1.18 2003/03/04 19:44:10 nathanw Exp $"); #endif #endif /* LIBC_SCCS and not lint */ @@ -50,7 +50,11 @@ __RCSID("$NetBSD: system.c,v 1.17 2001/10/31 13:31:26 kleink Exp $"); #include <stdlib.h> #include <unistd.h> #include <paths.h> +#include "reentrant.h" +#ifdef _REENTRANT +extern rwlock_t __environ_lock; +#endif extern char **environ; int @@ -80,8 +84,10 @@ system(command) if (sigprocmask(SIG_BLOCK, &nmask, &omask) == -1) return -1; + rwlock_rdlock(&__environ_lock); switch(pid = vfork()) { case -1: /* error */ + rwlock_unlock(&__environ_lock); sigaction(SIGINT, &intsa, NULL); sigaction(SIGQUIT, &quitsa, NULL); (void)sigprocmask(SIG_SETMASK, &omask, NULL); @@ -93,6 +99,7 @@ system(command) execve(_PATH_BSHELL, argp, environ); _exit(127); } + rwlock_unlock(&__environ_lock); while (waitpid(pid, &pstat, 0) == -1) { if (errno != EINTR) { |
