diff options
-rw-r--r-- | libbb/run_parts.c | 40 |
1 files changed, 17 insertions, 23 deletions
diff --git a/libbb/run_parts.c b/libbb/run_parts.c index 1cd13f218..58645660b 100644 --- a/libbb/run_parts.c +++ b/libbb/run_parts.c @@ -83,37 +83,31 @@ extern int run_parts(char **args, const unsigned char test_mode) if (test_mode & 1) { puts(filename); } else { - pid_t pid, wpid; + /* exec_errno is common vfork variable */ + volatile int exec_errno = 0; int result; + int pid; if ((pid = vfork()) < 0) { bb_perror_msg_and_die("failed to fork"); - } else if (pid==0) { + } else if (!pid) { + args[0] = filename; execv(filename, args); + exec_errno = errno; _exit(1); } - /* Wait for the child process to exit. Since we use vfork - * we shouldn't actually have to do any waiting... */ - wpid = wait(&result); - while (wpid > 0) { - /* Find out who died, make sure it is the right process */ - if (pid == wpid) { - if (WIFEXITED(result) && WEXITSTATUS(result)) { - bb_perror_msg("%s exited with return code %d", filename, WEXITSTATUS(result)); - exitstatus = 1; - } else if (WIFSIGNALED(result) && WIFSIGNALED(result)) { - int sig; - sig = WTERMSIG(result); - bb_perror_msg("%s exited because of uncaught signal %d (%s)", - filename, sig, u_signal_names(0, &sig, 1)); - exitstatus = 1; - } - break; - } else { - /* Just in case some _other_ random child process exits */ - wpid = wait(&result); - } + waitpid(pid, &result, 0); + if(exec_errno) { + errno = exec_errno; + bb_perror_msg_and_die("failed to exec %s", filename); + } + if (WIFEXITED(result) && WEXITSTATUS(result)) { + bb_perror_msg("%s exited with return code %d", filename, WEXITSTATUS(result)); + exitstatus = 1; + } else if (WIFSIGNALED(result)) { + bb_perror_msg("%s exited because of uncaught signal %d", filename, WTERMSIG(result)); + exitstatus = 1; } } } |