summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorguenther <>2015-10-23 04:44:41 +0000
committerguenther <>2015-10-23 04:44:41 +0000
commit39d5aee63717e002ef61a78d0d84c18f07b53e91 (patch)
treee9595f766fb8bbb27ab3c7ccc38a55fadb192b7f /src
parent0318167b7689b32eb9d5c7f8d5de7eada56299b7 (diff)
downloadopenbsd-39d5aee63717e002ef61a78d0d84c18f07b53e91.tar.gz
openbsd-39d5aee63717e002ef61a78d0d84c18f07b53e91.tar.bz2
openbsd-39d5aee63717e002ef61a78d0d84c18f07b53e91.zip
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 'src')
-rw-r--r--src/lib/libc/stdlib/system.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/src/lib/libc/stdlib/system.c b/src/lib/libc/stdlib/system.c
index 3ad0bcde41..de32d4328f 100644
--- a/src/lib/libc/stdlib/system.c
+++ b/src/lib/libc/stdlib/system.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: system.c,v 1.10 2015/09/14 08:51:07 guenther Exp $ */ 1/* $OpenBSD: system.c,v 1.11 2015/10/23 04:44:41 guenther Exp $ */
2/* 2/*
3 * Copyright (c) 1988 The Regents of the University of California. 3 * Copyright (c) 1988 The Regents of the University of California.
4 * All rights reserved. 4 * All rights reserved.
@@ -30,6 +30,7 @@
30 30
31#include <sys/types.h> 31#include <sys/types.h>
32#include <sys/wait.h> 32#include <sys/wait.h>
33#include <errno.h>
33#include <signal.h> 34#include <signal.h>
34#include <stdlib.h> 35#include <stdlib.h>
35#include <unistd.h> 36#include <unistd.h>
@@ -40,8 +41,8 @@ extern char **environ;
40int 41int
41system(const char *command) 42system(const char *command)
42{ 43{
43 pid_t pid; 44 pid_t pid, cpid;
44 sig_t intsave, quitsave; 45 struct sigaction intsave, quitsave;
45 sigset_t mask, omask; 46 sigset_t mask, omask;
46 int pstat; 47 int pstat;
47 char *argp[] = {"sh", "-c", NULL, NULL}; 48 char *argp[] = {"sh", "-c", NULL, NULL};
@@ -54,7 +55,7 @@ system(const char *command)
54 sigemptyset(&mask); 55 sigemptyset(&mask);
55 sigaddset(&mask, SIGCHLD); 56 sigaddset(&mask, SIGCHLD);
56 sigprocmask(SIG_BLOCK, &mask, &omask); 57 sigprocmask(SIG_BLOCK, &mask, &omask);
57 switch (pid = vfork()) { 58 switch (cpid = vfork()) {
58 case -1: /* error */ 59 case -1: /* error */
59 sigprocmask(SIG_SETMASK, &omask, NULL); 60 sigprocmask(SIG_SETMASK, &omask, NULL);
60 return(-1); 61 return(-1);
@@ -64,12 +65,14 @@ system(const char *command)
64 _exit(127); 65 _exit(127);
65 } 66 }
66 67
67 intsave = signal(SIGINT, SIG_IGN); 68 sigaction(SIGINT, NULL, &intsave);
68 quitsave = signal(SIGQUIT, SIG_IGN); 69 sigaction(SIGQUIT, NULL, &quitsave);
69 pid = waitpid(pid, &pstat, 0); 70 do {
71 pid = waitpid(cpid, &pstat, 0);
72 } while (pid == -1 && errno == EINTR);
70 sigprocmask(SIG_SETMASK, &omask, NULL); 73 sigprocmask(SIG_SETMASK, &omask, NULL);
71 (void)signal(SIGINT, intsave); 74 sigaction(SIGINT, &intsave, NULL);
72 (void)signal(SIGQUIT, quitsave); 75 sigaction(SIGQUIT, &quitsave, NULL);
73 return (pid == -1 ? -1 : pstat); 76 return (pid == -1 ? -1 : pstat);
74} 77}
75DEF_STRONG(system); 78DEF_STRONG(system);