diff --git a/console-tools/openvt.c b/console-tools/openvt.c index 6f58916e7..e3ea71bc5 100644 --- a/console-tools/openvt.c +++ b/console-tools/openvt.c @@ -97,8 +97,7 @@ static NOINLINE void vfork_child(char **argv) //bb_error_msg("our pgrp %d", getpgrp()); //bb_error_msg("VT's sid %d", tcgetsid(0)); //bb_error_msg("VT's pgrp %d", tcgetpgrp(0)); - BB_EXECVP(argv[0], argv); - bb_perror_msg_and_die("can't execute '%s'", argv[0]); + BB_EXECVP_or_die(argv); } } diff --git a/coreutils/chroot.c b/coreutils/chroot.c index bc0b1f82c..046c2fabf 100644 --- a/coreutils/chroot.c +++ b/coreutils/chroot.c @@ -30,6 +30,5 @@ int chroot_main(int argc UNUSED_PARAM, char **argv) argv[1] = (char *) "-i"; } - BB_EXECVP(argv[0], argv); - bb_perror_msg_and_die("can't execute '%s'", argv[0]); + BB_EXECVP_or_die(argv); } diff --git a/coreutils/env.c b/coreutils/env.c index c6ba04d35..d4eab191b 100644 --- a/coreutils/env.c +++ b/coreutils/env.c @@ -77,10 +77,7 @@ int env_main(int argc UNUSED_PARAM, char **argv) } if (argv[0]) { - BB_EXECVP(argv[0], argv); - /* SUSv3-mandated exit codes. */ - xfunc_error_retval = (errno == ENOENT) ? 127 : 126; - bb_perror_msg_and_die("can't execute '%s'", argv[0]); + BB_EXECVP_or_die(argv); } if (environ) { /* clearenv() may set environ == NULL! */ diff --git a/coreutils/nice.c b/coreutils/nice.c index 0f70f1079..ff3eb1140 100644 --- a/coreutils/nice.c +++ b/coreutils/nice.c @@ -47,8 +47,5 @@ int nice_main(int argc, char **argv) } } - BB_EXECVP(argv[0], argv); - /* The exec failed... */ - xfunc_error_retval = (errno == ENOENT) ? 127 : 126; /* SUSv3 */ - bb_perror_msg_and_die("can't execute '%s'", argv[0]); + BB_EXECVP_or_die(argv); } diff --git a/coreutils/nohup.c b/coreutils/nohup.c index 1027ada1c..3dc531409 100644 --- a/coreutils/nohup.c +++ b/coreutils/nohup.c @@ -76,6 +76,5 @@ int nohup_main(int argc UNUSED_PARAM, char **argv) signal(SIGHUP, SIG_IGN); argv++; - BB_EXECVP(argv[0], argv); - bb_perror_msg_and_die("can't execute '%s'", argv[0]); + BB_EXECVP_or_die(argv); } diff --git a/include/libbb.h b/include/libbb.h index e26001705..4b6699f2f 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -839,6 +839,7 @@ int bb_execvp(const char *file, char *const argv[]) FAST_FUNC; #define BB_EXECVP(prog,cmd) execvp(prog,cmd) #define BB_EXECLP(prog,cmd,...) execlp(prog,cmd, __VA_ARGS__) #endif +int BB_EXECVP_or_die(char **argv) NORETURN FAST_FUNC; /* NOMMU friendy fork+exec: */ pid_t spawn(char **argv) FAST_FUNC; diff --git a/libbb/execable.c b/libbb/execable.c index 5c7ac16a2..82241cd81 100644 --- a/libbb/execable.c +++ b/libbb/execable.c @@ -76,3 +76,11 @@ int FAST_FUNC bb_execvp(const char *file, char *const argv[]) argv); } #endif + +int FAST_FUNC BB_EXECVP_or_die(char **argv) +{ + BB_EXECVP(argv[0], argv); + /* SUSv3-mandated exit codes */ + xfunc_error_retval = (errno == ENOENT) ? 127 : 126; + bb_perror_msg_and_die("can't execute '%s'", argv[0]); +} diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c index 082f0f63e..8102ea2dc 100644 --- a/libbb/vfork_daemon_rexec.c +++ b/libbb/vfork_daemon_rexec.c @@ -67,40 +67,6 @@ pid_t FAST_FUNC xspawn(char **argv) return pid; } -pid_t FAST_FUNC safe_waitpid(pid_t pid, int *wstat, int options) -{ - pid_t r; - - do - r = waitpid(pid, wstat, options); - while ((r == -1) && (errno == EINTR)); - return r; -} - -pid_t FAST_FUNC wait_any_nohang(int *wstat) -{ - return safe_waitpid(-1, wstat, WNOHANG); -} - -// Wait for the specified child PID to exit, returning child's error return. -int FAST_FUNC wait4pid(pid_t pid) -{ - int status; - - if (pid <= 0) { - /*errno = ECHILD; -- wrong. */ - /* we expect errno to be already set from failed [v]fork/exec */ - return -1; - } - if (safe_waitpid(pid, &status, 0) == -1) - return -1; - if (WIFEXITED(status)) - return WEXITSTATUS(status); - if (WIFSIGNALED(status)) - return WTERMSIG(status) + 0x180; - return 0; -} - #if ENABLE_FEATURE_PREFER_APPLETS void FAST_FUNC save_nofork_data(struct nofork_save_area *save) { diff --git a/libbb/xfuncs.c b/libbb/xfuncs.c index 65437211d..275dd4b62 100644 --- a/libbb/xfuncs.c +++ b/libbb/xfuncs.c @@ -268,3 +268,37 @@ int FAST_FUNC tcsetattr_stdin_TCSANOW(const struct termios *tp) { return tcsetattr(STDIN_FILENO, TCSANOW, tp); } + +pid_t FAST_FUNC safe_waitpid(pid_t pid, int *wstat, int options) +{ + pid_t r; + + do + r = waitpid(pid, wstat, options); + while ((r == -1) && (errno == EINTR)); + return r; +} + +pid_t FAST_FUNC wait_any_nohang(int *wstat) +{ + return safe_waitpid(-1, wstat, WNOHANG); +} + +// Wait for the specified child PID to exit, returning child's error return. +int FAST_FUNC wait4pid(pid_t pid) +{ + int status; + + if (pid <= 0) { + /*errno = ECHILD; -- wrong. */ + /* we expect errno to be already set from failed [v]fork/exec */ + return -1; + } + if (safe_waitpid(pid, &status, 0) == -1) + return -1; + if (WIFEXITED(status)) + return WEXITSTATUS(status); + if (WIFSIGNALED(status)) + return WTERMSIG(status) + 0x180; + return 0; +} diff --git a/mailutils/mail.c b/mailutils/mail.c index 49e72c32b..5eb99e13d 100644 --- a/mailutils/mail.c +++ b/mailutils/mail.c @@ -67,8 +67,7 @@ void FAST_FUNC launch_helper(const char **argv) if (!G.helper_pid) { // child: try to execute connection helper // NB: SIGCHLD & SIGALRM revert to SIG_DFL on exec - BB_EXECVP(argv[0], (char **)argv); - bb_perror_msg_and_die("can't execute '%s'", argv[0]); + BB_EXECVP_or_die((char**)argv); } // parent diff --git a/mailutils/mime.c b/mailutils/mime.c index 654b8731c..5eb8ef6f2 100644 --- a/mailutils/mime.c +++ b/mailutils/mime.c @@ -288,8 +288,7 @@ static int parse(const char *boundary, char **argv) xsetenv("CHARSET", charset); xsetenv("ENCODING", encoding); xsetenv("FILENAME", filename); - BB_EXECVP(argv[0], argv); - bb_perror_msg_and_die("can't execute '%s'", argv[0]); + BB_EXECVP_or_die(argv); } // parent dumps to fd[1] close(fd[0]); diff --git a/miscutils/chrt.c b/miscutils/chrt.c index 3d0da58ca..d5f87c4d7 100644 --- a/miscutils/chrt.c +++ b/miscutils/chrt.c @@ -120,6 +120,5 @@ int chrt_main(int argc UNUSED_PARAM, char **argv) if (!argv[0]) /* "-p [...]" */ goto print_rt_info; - BB_EXECVP(argv[0], argv); - bb_perror_msg_and_die("can't execute '%s'", argv[0]); + BB_EXECVP_or_die(argv); } diff --git a/miscutils/ionice.c b/miscutils/ionice.c index 8393cd8b2..52e51b908 100644 --- a/miscutils/ionice.c +++ b/miscutils/ionice.c @@ -90,8 +90,7 @@ int ionice_main(int argc UNUSED_PARAM, char **argv) if (ioprio_set(IOPRIO_WHO_PROCESS, pid, pri) == -1) bb_perror_msg_and_die("ioprio_%cet", 's'); if (argv[0]) { - BB_EXECVP(argv[0], argv); - bb_perror_msg_and_die("can't execute '%s'", argv[0]); + BB_EXECVP_or_die(argv); } } diff --git a/miscutils/setsid.c b/miscutils/setsid.c index 60ee062e3..c573fae34 100644 --- a/miscutils/setsid.c +++ b/miscutils/setsid.c @@ -45,6 +45,5 @@ int setsid_main(int argc UNUSED_PARAM, char **argv) } argv++; - BB_EXECVP(argv[0], argv); - bb_perror_msg_and_die("can't execute '%s'", argv[0]); + BB_EXECVP_or_die(argv); } diff --git a/miscutils/taskset.c b/miscutils/taskset.c index 2891003df..08198d5d4 100644 --- a/miscutils/taskset.c +++ b/miscutils/taskset.c @@ -132,6 +132,5 @@ int taskset_main(int argc UNUSED_PARAM, char **argv) if (!argv[0]) /* "-p [...ignored...]" */ goto print_aff; /* print new affinity and exit */ - BB_EXECVP(argv[0], argv); - bb_perror_msg_and_die("can't execute '%s'", argv[0]); + BB_EXECVP_or_die(argv); } diff --git a/miscutils/time.c b/miscutils/time.c index f5d1e15fb..5cfbcef8e 100644 --- a/miscutils/time.c +++ b/miscutils/time.c @@ -367,20 +367,17 @@ static void summarize(const char *fmt, char **command, resource_t *resp) Put the statistics in *RESP. */ static void run_command(char *const *cmd, resource_t *resp) { - pid_t pid; /* Pid of child. */ + pid_t pid; void (*interrupt_signal)(int); void (*quit_signal)(int); resp->elapsed_ms = monotonic_ms(); - pid = vfork(); /* Run CMD as child process. */ + pid = vfork(); if (pid < 0) - bb_perror_msg_and_die("fork"); - if (pid == 0) { /* If child. */ - /* Don't cast execvp arguments; that causes errors on some systems, - versus merely warnings if the cast is left off. */ - BB_EXECVP(cmd[0], cmd); - xfunc_error_retval = (errno == ENOENT ? 127 : 126); - bb_perror_msg_and_die("can't execute '%s'", cmd[0]); + bb_perror_msg_and_die("vfork"); + if (pid == 0) { + /* Child */ + BB_EXECVP_or_die((char**)cmd); } /* Have signals kill the child but not self (if possible). */ diff --git a/miscutils/timeout.c b/miscutils/timeout.c index 273d26953..f6e655acc 100644 --- a/miscutils/timeout.c +++ b/miscutils/timeout.c @@ -110,6 +110,5 @@ int timeout_main(int argc UNUSED_PARAM, char **argv) argv[0] = sv1; argv[1] = sv2; #endif - BB_EXECVP(argv[0], argv); - bb_perror_msg_and_die("can't execute '%s'", argv[0]); + BB_EXECVP_or_die(argv); } diff --git a/networking/ifupdown.c b/networking/ifupdown.c index 714d2a107..1bab2c5cb 100644 --- a/networking/ifupdown.c +++ b/networking/ifupdown.c @@ -1052,8 +1052,7 @@ static int popen2(FILE **in, FILE **out, char *command, char *param) close(outfd.rd); xmove_fd(infd.rd, 0); xmove_fd(outfd.wr, 1); - BB_EXECVP(command, argv); - bb_perror_msg_and_die("can't execute '%s'", command); + BB_EXECVP_or_die(argv); } /* parent */ close(infd.rd); diff --git a/networking/tcpudp.c b/networking/tcpudp.c index 4e4756738..53e622b56 100644 --- a/networking/tcpudp.c +++ b/networking/tcpudp.c @@ -501,10 +501,10 @@ int tcpudpsvd_main(int argc UNUSED_PARAM, char **argv) #ifdef SSLSVD strcpy(id, utoa(pid)); ssl_io(0, argv); -#else - BB_EXECVP(argv[0], argv); -#endif bb_perror_msg_and_die("can't execute '%s'", argv[0]); +#else + BB_EXECVP_or_die(argv); +#endif } /* diff --git a/printutils/lpd.c b/printutils/lpd.c index 15f1ba20b..d91491f1b 100644 --- a/printutils/lpd.c +++ b/printutils/lpd.c @@ -181,8 +181,7 @@ int lpd_main(int argc UNUSED_PARAM, char *argv[]) // this call reopens stdio fds to "/dev/null" // (no daemonization is done) bb_daemonize_or_rexec(DAEMON_DEVNULL_STDIO | DAEMON_ONLY_SANITIZE, NULL); - BB_EXECVP(argv[0], argv); - bb_perror_msg_and_die("can't execute '%s'", argv[0]); + BB_EXECVP_or_die(argv); } // validate input. diff --git a/runit/chpst.c b/runit/chpst.c index 028a28d6c..ad0811294 100644 --- a/runit/chpst.c +++ b/runit/chpst.c @@ -382,6 +382,5 @@ int chpst_main(int argc UNUSED_PARAM, char **argv) if (opt & OPT_2) close(STDERR_FILENO); - BB_EXECVP(argv[0], argv); - bb_perror_msg_and_die("can't execute '%s'", argv[0]); + BB_EXECVP_or_die(argv); } diff --git a/shell/cttyhack.c b/shell/cttyhack.c index bde2acdc9..67736ad62 100644 --- a/shell/cttyhack.c +++ b/shell/cttyhack.c @@ -81,6 +81,5 @@ int cttyhack_main(int argc UNUSED_PARAM, char **argv) } } - BB_EXECVP(argv[0], argv); - bb_perror_msg_and_die("can't execute '%s'", argv[0]); + BB_EXECVP_or_die(argv); }