diff options
Diffstat (limited to 'libbb')
-rw-r--r-- | libbb/vfork_daemon_rexec.c | 42 |
1 files changed, 39 insertions, 3 deletions
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c index ff2b0bceb..d25693917 100644 --- a/libbb/vfork_daemon_rexec.c +++ b/libbb/vfork_daemon_rexec.c @@ -16,7 +16,7 @@ */ #include <paths.h> -#include "libbb.h" +#include "busybox.h" /* for struct BB_applet */ /* This does a fork/exec in one call, using vfork(). Returns PID of new child, * -1 for failure. Runs argv[0], searching path if that has no / in it. */ @@ -72,7 +72,8 @@ int wait4pid(int pid) int status; if (pid <= 0) { - /*errno = ECHILD; -- wrong. we expect errno to be set from failed exec */ + /*errno = ECHILD; -- wrong. */ + /* we expect errno to be already set from failed [v]fork/exec */ return -1; } if (waitpid(pid, &status, 0) == -1) @@ -80,7 +81,7 @@ int wait4pid(int pid) if (WIFEXITED(status)) return WEXITSTATUS(status); if (WIFSIGNALED(status)) - return WTERMSIG(status) + 10000; + return WTERMSIG(status) + 1000; return 0; } @@ -99,6 +100,41 @@ int wait_pid(int *wstat, int pid) return r; } +int spawn_and_wait(char **argv) +{ + int rc; + + if (ENABLE_FEATURE_EXEC_PREFER_APPLETS) { + const struct BB_applet *a = find_applet_by_name(argv[0]); + if (a && (a->nofork +#ifndef BB_NOMMU + || a->noexec /* NOEXEC cannot be used on NOMMU */ +#endif + )) { + int argc = 1; + char **pp = argv; + while (*++pp) + argc++; +#ifdef BB_NOMMU + return a->main(argc, argv); +#else + if (a->nofork) + return a->main(argc, argv); + /* a->noexec is true */ + rc = fork(); + if (rc) + goto w; + /* child */ + current_applet = a; + run_current_applet_and_exit(argc, argv); +#endif + } + } + rc = spawn(argv); + w: + return wait4pid(rc); +} + #if 0 //ndef BB_NOMMU // Die with an error message if we can't daemonize. void xdaemon(int nochdir, int noclose) |