From 847bcb63b541e4fbbfa3dccfe3022745cbe9a06a Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Wed, 23 Sep 2015 22:18:22 -0500 Subject: Add xvfork() as a static inline and use it from various places. Note: vfork(), like fork(), can return -1 if too many processes, and we should notice and fail loudly. --- lib/lib.h | 12 ++++++++++++ toys/other/setsid.c | 4 ++-- toys/other/timeout.c | 2 +- toys/pending/sh.c | 2 +- toys/posix/time.c | 2 +- toys/posix/xargs.c | 2 +- 6 files changed, 18 insertions(+), 6 deletions(-) diff --git a/lib/lib.h b/lib/lib.h index 2b49dc17..cbac3aa5 100644 --- a/lib/lib.h +++ b/lib/lib.h @@ -246,5 +246,17 @@ void mode_to_string(mode_t mode, char *buf); char *basename_r(char *name); void names_to_pid(char **names, int (*callback)(pid_t pid, char *name)); +// Returning from a function can modify a potentially shared stack, +// so this has to always inline. + +static inline pid_t xvfork(void) +{ + pid_t p = vfork(); + + if (p == -1) perror_exit("vfork"); + + return p; +} + // Functions in need of further review/cleanup #include "lib/pending.h" diff --git a/toys/other/setsid.c b/toys/other/setsid.c index 59a1d78f..83db044d 100644 --- a/toys/other/setsid.c +++ b/toys/other/setsid.c @@ -19,9 +19,9 @@ config SETSID void setsid_main(void) { - while (setsid()<0) if (vfork()) _exit(0); + while (setsid()<0) if (xvfork()) _exit(0); if (toys.optflags) { - setpgid(0,0); + setpgid(0, 0); tcsetpgrp(0, getpid()); } xexec(toys.optargs); diff --git a/toys/other/timeout.c b/toys/other/timeout.c index 06b1e89a..bd716e63 100644 --- a/toys/other/timeout.c +++ b/toys/other/timeout.c @@ -62,7 +62,7 @@ void timeout_main(void) if (TT.s_signal && -1 == (TT.nextsig = sig_to_num(TT.s_signal))) error_exit("bad -s: '%s'", TT.s_signal); - if (!(TT.pid = xfork())) xexec(toys.optargs+1); + if (!(TT.pid = xvfork())) xexec(toys.optargs+1); else { int status; diff --git a/toys/pending/sh.c b/toys/pending/sh.c index 499c5dbd..87f2f9ff 100644 --- a/toys/pending/sh.c +++ b/toys/pending/sh.c @@ -305,7 +305,7 @@ static void run_pipeline(struct pipeline *line) } else { int status; - cmd->pid = vfork(); + cmd->pid = xvfork(); if (!cmd->pid) xexec(cmd->argv); else waitpid(cmd->pid, &status, 0); diff --git a/toys/posix/time.c b/toys/posix/time.c index 70d2997e..b3cfd26b 100644 --- a/toys/posix/time.c +++ b/toys/posix/time.c @@ -28,7 +28,7 @@ void time_main(void) struct timeval tv, tv2; gettimeofday(&tv, NULL); - if (!(pid = xfork())) xexec(toys.optargs); + if (!(pid = xvfork())) xexec(toys.optargs); else { int stat; struct rusage ru; diff --git a/toys/posix/xargs.c b/toys/posix/xargs.c index 8178bf0c..50c42620 100644 --- a/toys/posix/xargs.c +++ b/toys/posix/xargs.c @@ -168,7 +168,7 @@ void xargs_main(void) for (dtemp = dlist; dtemp; dtemp = dtemp->next) handle_entries(dtemp->data, out+entries); - pid_t pid=xfork(); + pid_t pid=xvfork(); if (!pid) { xclose(0); open("/dev/null", O_RDONLY); -- cgit v1.2.3