summaryrefslogtreecommitdiffstats
path: root/lib/libc/stdlib/system.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/stdlib/system.c')
-rw-r--r--lib/libc/stdlib/system.c38
1 files changed, 19 insertions, 19 deletions
diff --git a/lib/libc/stdlib/system.c b/lib/libc/stdlib/system.c
index b552a63..64a5447 100644
--- a/lib/libc/stdlib/system.c
+++ b/lib/libc/stdlib/system.c
@@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
#include <signal.h>
#include <stdlib.h>
#include <stddef.h>
+#include <string.h>
#include <unistd.h>
#include <paths.h>
#include <errno.h>
@@ -56,37 +57,36 @@ __system(const char *command)
if (!command) /* just checking... */
return(1);
- /*
- * Ignore SIGINT and SIGQUIT, block SIGCHLD. Remember to save
- * existing signal dispositions.
- */
- ign.sa_handler = SIG_IGN;
- (void)sigemptyset(&ign.sa_mask);
- ign.sa_flags = 0;
- (void)_sigaction(SIGINT, &ign, &intact);
- (void)_sigaction(SIGQUIT, &ign, &quitact);
(void)sigemptyset(&newsigblock);
(void)sigaddset(&newsigblock, SIGCHLD);
(void)_sigprocmask(SIG_BLOCK, &newsigblock, &oldsigblock);
- switch(pid = fork()) {
+ switch(pid = vfork()) {
case -1: /* error */
- break;
+ (void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL);
+ return (-1);
case 0: /* child */
/*
* Restore original signal dispositions and exec the command.
*/
- (void)_sigaction(SIGINT, &intact, NULL);
- (void)_sigaction(SIGQUIT, &quitact, NULL);
(void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL);
execl(_PATH_BSHELL, "sh", "-c", command, (char *)NULL);
_exit(127);
- default: /* parent */
- savedpid = pid;
- do {
- pid = _wait4(savedpid, &pstat, 0, (struct rusage *)0);
- } while (pid == -1 && errno == EINTR);
- break;
}
+ /*
+ * If we are running means that the child has either completed
+ * its execve, or has failed.
+ * Block SIGINT/QUIT because sh -c handles it and wait for
+ * it to clean up.
+ */
+ memset(&ign, 0, sizeof(ign));
+ ign.sa_handler = SIG_IGN;
+ (void)sigemptyset(&ign.sa_mask);
+ (void)_sigaction(SIGINT, &ign, &intact);
+ (void)_sigaction(SIGQUIT, &ign, &quitact);
+ savedpid = pid;
+ do {
+ pid = _wait4(savedpid, &pstat, 0, (struct rusage *)0);
+ } while (pid == -1 && errno == EINTR);
(void)_sigaction(SIGINT, &intact, NULL);
(void)_sigaction(SIGQUIT, &quitact, NULL);
(void)_sigprocmask(SIG_SETMASK, &oldsigblock, NULL);
OpenPOWER on IntegriCloud