libbb: introduce and use BB_EXECVP_or_die()
No binary (build failed)
—
(log yok)
| @@ -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); |
| } | |
| } | |
| @@ -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); |
| } | |
| @@ -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! */ | |
| @@ -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); |
| } | |
| @@ -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); |
| } | |
| @@ -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; | |
| @@ -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]); |
| + | } |
| @@ -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) | |
| { | |
| @@ -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; |
| + | } |
| @@ -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 | |
| @@ -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]); | |
| @@ -120,6 +120,5 @@ int chrt_main(int argc UNUSED_PARAM, char **argv) | |
| if (!argv[0]) /* "-p <priority> <pid> [...]" */ | |
| 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); |
| } | |
| @@ -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); |
| } | |
| } | |
| @@ -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); |
| } | |
| @@ -132,6 +132,5 @@ int taskset_main(int argc UNUSED_PARAM, char **argv) | |
| if (!argv[0]) /* "-p <aff> <pid> [...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); |
| } | |
| @@ -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). */ | |
| @@ -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); |
| } | |
| @@ -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); | |
| @@ -501,10 +501,10 @@ int tcpudpsvd_main(int argc UNUSED_PARAM, char **argv) | |
| #ifdef SSLSVD | |
| strcpy(id, utoa(pid)); | |
| ssl_io(0, argv); | |
| + | bb_perror_msg_and_die("can't execute '%s'", argv[0]); |
| #else | |
| - | BB_EXECVP(argv[0], argv); |
| + | BB_EXECVP_or_die(argv); |
| #endif | |
| - | bb_perror_msg_and_die("can't execute '%s'", argv[0]); |
| } | |
| /* | |
| @@ -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. | |
| @@ -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); |
| } | |
| @@ -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); |
| } | |