diff options
author | Glenn L McGrath <bug1@ihug.co.nz> | 2002-11-15 22:18:01 +0000 |
---|---|---|
committer | Glenn L McGrath <bug1@ihug.co.nz> | 2002-11-15 22:18:01 +0000 |
commit | 39289b54a74a37e485adac39dec17938ac568b3c (patch) | |
tree | 57dfed64b1a719f7196d44d3c26c254074c08814 | |
parent | 02fcd2d2df00ec2e79f1cc30c7a7badb60548671 (diff) | |
download | busybox-w32-39289b54a74a37e485adac39dec17938ac568b3c.tar.gz busybox-w32-39289b54a74a37e485adac39dec17938ac568b3c.tar.bz2 busybox-w32-39289b54a74a37e485adac39dec17938ac568b3c.zip |
Use vfork, by vodz
-rw-r--r-- | libbb/run_parts.c | 64 |
1 files changed, 22 insertions, 42 deletions
diff --git a/libbb/run_parts.c b/libbb/run_parts.c index bf906a399..8399a6afb 100644 --- a/libbb/run_parts.c +++ b/libbb/run_parts.c | |||
@@ -1,53 +1,20 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | 1 | /* vi: set sw=4 ts=4: */ |
2 | /* | 2 | /* |
3 | * Mini run-parts implementation for busybox | 3 | * run command from specified directory |
4 | * | 4 | * |
5 | * | 5 | * |
6 | * Copyright (C) 2001 by Emanuele Aina <emanuele.aina@tiscali.it> | 6 | * Copyright (C) 2001 by Emanuele Aina <emanuele.aina@tiscali.it> |
7 | * | 7 | * rewrite to vfork usage by |
8 | * Based on the Debian run-parts program, version 1.15 | 8 | * Copyright (C) 2002 by Vladimir Oleynik <dzo@simtreas.ru> |
9 | * Copyright (C) 1996 Jeff Noxon <jeff@router.patch.net>, | ||
10 | * Copyright (C) 1996-1999 Guy Maor <maor@debian.org> | ||
11 | * | ||
12 | * | 9 | * |
13 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
14 | * it under the terms of the GNU General Public License as published by | 11 | * it under the terms of the GNU General Public License as published by |
15 | * the Free Software Foundation; either version 2 of the License, or | 12 | * the Free Software Foundation; either version 2 of the License, or |
16 | * (at your option) any later version. | 13 | * (at your option) any later version. |
17 | * | 14 | * |
18 | * This program is distributed in the hope that it will be useful, | ||
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
21 | * General Public License for more details. | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; if not, write to the Free Software | ||
25 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
26 | * 02111-1307 USA | ||
27 | * | 15 | * |
28 | */ | 16 | */ |
29 | 17 | ||
30 | /* This is my first attempt to write a program in C (well, this is my first | ||
31 | * attempt to write a program! :-) . */ | ||
32 | |||
33 | /* This piece of code is heavily based on the original version of run-parts, | ||
34 | * taken from debian-utils. I've only removed the long options and a the | ||
35 | * report mode. As the original run-parts support only long options, I've | ||
36 | * broken compatibility because the BusyBox policy doesn't allow them. | ||
37 | * The supported options are: | ||
38 | * -t test. Print the name of the files to be executed, without | ||
39 | * execute them. | ||
40 | * -a ARG argument. Pass ARG as an argument the program executed. It can | ||
41 | * be repeated to pass multiple arguments. | ||
42 | * -u MASK umask. Set the umask of the program executed to MASK. */ | ||
43 | |||
44 | /* TODO | ||
45 | * done - convert calls to error in perror... and remove error() | ||
46 | * done - convert malloc/realloc to their x... counterparts | ||
47 | * done - remove catch_sigchld | ||
48 | * done - use bb's concat_path_file() | ||
49 | * done - declare run_parts_main() as extern and any other function as static? | ||
50 | */ | ||
51 | 18 | ||
52 | #include <sys/types.h> | 19 | #include <sys/types.h> |
53 | #include <sys/wait.h> | 20 | #include <sys/wait.h> |
@@ -55,6 +22,7 @@ | |||
55 | #include <dirent.h> | 22 | #include <dirent.h> |
56 | #include <unistd.h> | 23 | #include <unistd.h> |
57 | #include <ctype.h> | 24 | #include <ctype.h> |
25 | #include <errno.h> | ||
58 | 26 | ||
59 | #include "libbb.h" | 27 | #include "libbb.h" |
60 | 28 | ||
@@ -86,6 +54,11 @@ extern int run_parts(char **args, const unsigned char test_mode) | |||
86 | int i; | 54 | int i; |
87 | int exitstatus = 0; | 55 | int exitstatus = 0; |
88 | 56 | ||
57 | #if __GNUC__ | ||
58 | /* Avoid longjmp clobbering */ | ||
59 | (void) &i; | ||
60 | (void) &exitstatus; | ||
61 | #endif | ||
89 | /* scandir() isn't POSIX, but it makes things easy. */ | 62 | /* scandir() isn't POSIX, but it makes things easy. */ |
90 | entries = scandir(args[0], &namelist, valid_name, alphasort); | 63 | entries = scandir(args[0], &namelist, valid_name, alphasort); |
91 | 64 | ||
@@ -104,23 +77,30 @@ extern int run_parts(char **args, const unsigned char test_mode) | |||
104 | if (test_mode) | 77 | if (test_mode) |
105 | printf("run-parts would run %s\n", filename); | 78 | printf("run-parts would run %s\n", filename); |
106 | else { | 79 | else { |
80 | /* exec_errno is common vfork variable */ | ||
81 | volatile int exec_errno = 0; | ||
107 | int result; | 82 | int result; |
108 | int pid; | 83 | int pid; |
109 | 84 | ||
110 | if ((pid = fork()) < 0) { | 85 | if ((pid = vfork()) < 0) { |
111 | perror_msg_and_die("failed to fork"); | 86 | perror_msg_and_die("failed to fork"); |
112 | } else if (!pid) { | 87 | } else if (!pid) { |
113 | execv(args[0], args); | 88 | args[0] = filename; |
114 | perror_msg_and_die("failed to exec %s", args[0]); | 89 | execv(filename, args); |
90 | exec_errno = errno; | ||
91 | _exit(1); | ||
115 | } | 92 | } |
116 | 93 | ||
117 | waitpid(pid, &result, 0); | 94 | waitpid(pid, &result, 0); |
118 | 95 | if(exec_errno) { | |
96 | errno = exec_errno; | ||
97 | perror_msg_and_die("failed to exec %s", filename); | ||
98 | } | ||
119 | if (WIFEXITED(result) && WEXITSTATUS(result)) { | 99 | if (WIFEXITED(result) && WEXITSTATUS(result)) { |
120 | perror_msg("%s exited with return code %d", args[0], WEXITSTATUS(result)); | 100 | perror_msg("%s exited with return code %d", filename, WEXITSTATUS(result)); |
121 | exitstatus = 1; | 101 | exitstatus = 1; |
122 | } else if (WIFSIGNALED(result)) { | 102 | } else if (WIFSIGNALED(result)) { |
123 | perror_msg("%s exited because of uncaught signal %d", args[0], WTERMSIG(result)); | 103 | perror_msg("%s exited because of uncaught signal %d", filename, WTERMSIG(result)); |
124 | exitstatus = 1; | 104 | exitstatus = 1; |
125 | } | 105 | } |
126 | } | 106 | } |