diff options
author | Philip Guenther <guenther@cvs.openbsd.org> | 2015-10-23 04:44:42 +0000 |
---|---|---|
committer | Philip Guenther <guenther@cvs.openbsd.org> | 2015-10-23 04:44:42 +0000 |
commit | f64e9c458671e52962711eede2a8842c4ab11d56 (patch) | |
tree | bac08fb1b1df675cfdc05ea6eb96079ab0a10430 /lib/libc/stdlib | |
parent | a982c64703a6852d4518f8dee8a656db84842b70 (diff) |
Loop the waitpid() on EINTR, and save and restore the disposition of
SIGINT and SIGQUIT with sigaction() instead of signal() so that all bits
are preserved.
ok deraadt@ millert@
Diffstat (limited to 'lib/libc/stdlib')
-rw-r--r-- | lib/libc/stdlib/system.c | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/lib/libc/stdlib/system.c b/lib/libc/stdlib/system.c index 3ad0bcde413..de32d4328f7 100644 --- a/lib/libc/stdlib/system.c +++ b/lib/libc/stdlib/system.c @@ -1,4 +1,4 @@ -/* $OpenBSD: system.c,v 1.10 2015/09/14 08:51:07 guenther Exp $ */ +/* $OpenBSD: system.c,v 1.11 2015/10/23 04:44:41 guenther Exp $ */ /* * Copyright (c) 1988 The Regents of the University of California. * All rights reserved. @@ -30,6 +30,7 @@ #include <sys/types.h> #include <sys/wait.h> +#include <errno.h> #include <signal.h> #include <stdlib.h> #include <unistd.h> @@ -40,8 +41,8 @@ extern char **environ; int system(const char *command) { - pid_t pid; - sig_t intsave, quitsave; + pid_t pid, cpid; + struct sigaction intsave, quitsave; sigset_t mask, omask; int pstat; char *argp[] = {"sh", "-c", NULL, NULL}; @@ -54,7 +55,7 @@ system(const char *command) sigemptyset(&mask); sigaddset(&mask, SIGCHLD); sigprocmask(SIG_BLOCK, &mask, &omask); - switch (pid = vfork()) { + switch (cpid = vfork()) { case -1: /* error */ sigprocmask(SIG_SETMASK, &omask, NULL); return(-1); @@ -64,12 +65,14 @@ system(const char *command) _exit(127); } - intsave = signal(SIGINT, SIG_IGN); - quitsave = signal(SIGQUIT, SIG_IGN); - pid = waitpid(pid, &pstat, 0); + sigaction(SIGINT, NULL, &intsave); + sigaction(SIGQUIT, NULL, &quitsave); + do { + pid = waitpid(cpid, &pstat, 0); + } while (pid == -1 && errno == EINTR); sigprocmask(SIG_SETMASK, &omask, NULL); - (void)signal(SIGINT, intsave); - (void)signal(SIGQUIT, quitsave); + sigaction(SIGINT, &intsave, NULL); + sigaction(SIGQUIT, &quitsave, NULL); return (pid == -1 ? -1 : pstat); } DEF_STRONG(system); |