X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=libbb%2Frun_parts.c;h=c1a45e3d908b8edf5dc5ac5d4822b1553131b567;hb=ddec5af6b0803c7434a1cc2fdee5cb9873fe6bd0;hp=1cd13f218ba3511b57144424e0ab0e8bd1e32f29;hpb=b0cfca75442293b4b670584d83c39f9cea9f5a8b;p=oweals%2Fbusybox.git diff --git a/libbb/run_parts.c b/libbb/run_parts.c index 1cd13f218..c1a45e3d9 100644 --- a/libbb/run_parts.c +++ b/libbb/run_parts.c @@ -7,12 +7,7 @@ * rewrite to vfork usage by * Copyright (C) 2002 by Vladimir Oleynik * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * + * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. */ @@ -32,7 +27,7 @@ */ static int valid_name(const struct dirent *d) { - char *c = d->d_name; + const char *c = d->d_name; while (*c) { if (!isalnum(*c) && (*c != '_') && (*c != '-')) { @@ -43,11 +38,11 @@ static int valid_name(const struct dirent *d) return 1; } -/* test mode = 1 is the same as offical run_parts - * test_mode = 2 means to fail siliently on missing directories +/* test mode = 1 is the same as official run_parts + * test_mode = 2 means to fail silently on missing directories */ -extern int run_parts(char **args, const unsigned char test_mode) +int run_parts(char **args, const unsigned char test_mode, char **env) { struct dirent **namelist = 0; struct stat st; @@ -69,54 +64,47 @@ extern int run_parts(char **args, const unsigned char test_mode) if (test_mode & 2) { return(2); } - bb_perror_msg_and_die("failed to open directory %s", arg0); + bb_perror_msg_and_die("unable to open `%s'", arg0); } for (i = 0; i < entries; i++) { filename = concat_path_file(arg0, namelist[i]->d_name); - if (stat(filename, &st) < 0) { - bb_perror_msg_and_die("failed to stat component %s", filename); - } + xstat(filename, &st); if (S_ISREG(st.st_mode) && !access(filename, X_OK)) { - if (test_mode & 1) { + if (test_mode) { 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) { - execv(filename, args); + } else if (!pid) { + args[0] = filename; + execve(filename, args, env); + 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("failed to exec %s", filename); + exitstatus = 1; + } + 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; } } - } + } else if (!S_ISDIR(st.st_mode)) { bb_error_msg("component %s is not an executable plain file", filename); exitstatus = 1; @@ -126,6 +114,6 @@ extern int run_parts(char **args, const unsigned char test_mode) free(filename); } free(namelist); - + return(exitstatus); }