Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/lib/libc/stdlib system(3): Switch from vfork/execve to posix...
details: https://anonhg.NetBSD.org/src/rev/404781ec07ee
branches: trunk
changeset: 363905:404781ec07ee
user: riastradh <riastradh%NetBSD.org@localhost>
date: Mon Mar 14 22:06:28 2022 +0000
description:
system(3): Switch from vfork/execve to posix_spawn.
Changes by me:
- Minor style nits.
- Set errno on posix_spawn failure.
- Handle edge cases of SIGINT/SIGQUIT set to SIG_IGN by caller.
Author: Nikita Ronja Gillmann <nikita%NetBSD.org@localhost>
Committer: Taylor R Campbell <riastradh%NetBSD.org@localhost>
diffstat:
lib/libc/stdlib/system.c | 59 +++++++++++++++++++++++++++++++++--------------
1 files changed, 41 insertions(+), 18 deletions(-)
diffs (105 lines):
diff -r ce8eb915fe4c -r 404781ec07ee lib/libc/stdlib/system.c
--- a/lib/libc/stdlib/system.c Mon Mar 14 21:38:04 2022 +0000
+++ b/lib/libc/stdlib/system.c Mon Mar 14 22:06:28 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: system.c,v 1.26 2021/10/29 19:27:06 kre Exp $ */
+/* $NetBSD: system.c,v 1.27 2022/03/14 22:06:28 riastradh Exp $ */
/*
* Copyright (c) 1988, 1993
@@ -34,7 +34,7 @@
#if 0
static char sccsid[] = "@(#)system.c 8.1 (Berkeley) 6/4/93";
#else
-__RCSID("$NetBSD: system.c,v 1.26 2021/10/29 19:27:06 kre Exp $");
+__RCSID("$NetBSD: system.c,v 1.27 2022/03/14 22:06:28 riastradh Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@@ -46,6 +46,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <paths.h>
+#include <spawn.h>
#include "env.h"
@@ -54,9 +55,12 @@
{
pid_t pid;
struct sigaction intsa, quitsa, sa;
- sigset_t nmask, omask;
+ sigset_t nmask, omask, sigdefault;
int pstat;
const char *argp[] = {"sh", "-c", "--", NULL, NULL};
+ posix_spawnattr_t attr;
+ int error;
+
argp[3] = command;
/*
@@ -88,22 +92,41 @@
return -1;
}
+ /*
+ * We arrange to inherit all signal handlers from the caller by
+ * default, except possibly SIGINT and SIGQUIT. These we have
+ * overridden internally for system(3) to be SIG_IGN.
+ *
+ * - If the caller had SIGINT or SIGQUIT at SIG_IGN, then we
+ * inherit them as is -- caller had SIG_IGN, child will too.
+ *
+ * - Otherwise, they are SIG_DFL or a signal handler, and we
+ * must reset them to SIG_DFL in the child, rather than
+ * SIG_IGN in system(3) in the parent, by including them in
+ * the sigdefault set.
+ */
+ sigemptyset(&sigdefault);
+ if (intsa.sa_handler != SIG_IGN)
+ sigaddset(&sigdefault, SIGINT);
+ if (quitsa.sa_handler != SIG_IGN)
+ sigaddset(&sigdefault, SIGQUIT);
+
+ posix_spawnattr_init(&attr);
+ posix_spawnattr_setsigdefault(&attr, &sigdefault);
+ posix_spawnattr_setsigmask(&attr, &omask);
+ posix_spawnattr_setflags(&attr,
+ POSIX_SPAWN_SETSIGDEF|POSIX_SPAWN_SETSIGMASK);
(void)__readlockenv();
- switch(pid = vfork()) {
- case -1: /* error */
- (void)__unlockenv();
- sigaction(SIGINT, &intsa, NULL);
- sigaction(SIGQUIT, &quitsa, NULL);
- (void)sigprocmask(SIG_SETMASK, &omask, NULL);
- return -1;
- case 0: /* child */
- sigaction(SIGINT, &intsa, NULL);
- sigaction(SIGQUIT, &quitsa, NULL);
- (void)sigprocmask(SIG_SETMASK, &omask, NULL);
- execve(_PATH_BSHELL, __UNCONST(argp), environ);
- _exit(127);
+ error = posix_spawn(&pid, _PATH_BSHELL, NULL, &attr, __UNCONST(argp),
+ environ);
+ (void)__unlockenv();
+ posix_spawnattr_destroy(&attr);
+
+ if (error) {
+ errno = error;
+ pstat = -1;
+ goto out;
}
- (void)__unlockenv();
while (waitpid(pid, &pstat, 0) == -1) {
if (errno != EINTR) {
@@ -112,7 +135,7 @@
}
}
- sigaction(SIGINT, &intsa, NULL);
+out: sigaction(SIGINT, &intsa, NULL);
sigaction(SIGQUIT, &quitsa, NULL);
(void)sigprocmask(SIG_SETMASK, &omask, NULL);
Home |
Main Index |
Thread Index |
Old Index