summaryrefslogtreecommitdiff
path: root/lib/libc/stdlib
diff options
context:
space:
mode:
authorPhilip Guenther <guenther@cvs.openbsd.org>2015-10-23 04:44:42 +0000
committerPhilip Guenther <guenther@cvs.openbsd.org>2015-10-23 04:44:42 +0000
commitf64e9c458671e52962711eede2a8842c4ab11d56 (patch)
treebac08fb1b1df675cfdc05ea6eb96079ab0a10430 /lib/libc/stdlib
parenta982c64703a6852d4518f8dee8a656db84842b70 (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.c21
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);