3 @@ -7394,23 +7394,8 @@ static int builtinloc = -1; /* index
7 -tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) char *cmd, char **argv, char **envp)
8 +tryexec(char *cmd, char **argv, char **envp)
10 -#if ENABLE_FEATURE_SH_STANDALONE
11 - if (applet_no >= 0) {
12 - if (APPLET_IS_NOEXEC(applet_no)) {
16 - run_applet_no_and_exit(applet_no, argv);
18 - /* re-exec ourselves with the new arguments */
19 - execve(bb_busybox_exec_path, argv, envp);
20 - /* If they called chroot or otherwise made the binary no longer
21 - * executable, fall through */
28 @@ -7471,30 +7456,21 @@ shellexec(char **argv, const char *path,
32 - int applet_no = -1; /* used only by FEATURE_SH_STANDALONE */
34 clearredir(/*drop:*/ 1);
35 envp = listvars(VEXPORT, VUNSET, /*end:*/ NULL);
36 - if (strchr(argv[0], '/') != NULL
37 -#if ENABLE_FEATURE_SH_STANDALONE
38 - || (applet_no = find_applet_by_name(argv[0])) >= 0
41 - tryexec(IF_FEATURE_SH_STANDALONE(applet_no,) argv[0], argv, envp);
42 - if (applet_no >= 0) {
43 - /* We tried execing ourself, but it didn't work.
44 - * Maybe /proc/self/exe doesn't exist?
49 + if (strchr(argv[0], '/') != NULL) {
50 + tryexec(argv[0], argv, envp);
54 +#if ENABLE_FEATURE_SH_STANDALONE
55 + bb_execv_applet(argv[0], argv, envp);
59 while ((cmdname = path_advance(&path, argv[0])) != NULL) {
60 if (--idx < 0 && pathopt == NULL) {
61 - tryexec(IF_FEATURE_SH_STANDALONE(-1,) cmdname, argv, envp);
62 + tryexec(cmdname, argv, envp);
63 if (errno != ENOENT && errno != ENOTDIR)
66 --- a/libbb/execable.c
67 +++ b/libbb/execable.c
75 /* check if path points to an executable file;
78 @@ -68,13 +71,60 @@ int FAST_FUNC exists_execable(const char
81 #if ENABLE_FEATURE_PREFER_APPLETS
82 +int FAST_FUNC bb_execv_applet(const char *name, char *const argv[], char *const envp[])
84 + const char **path = bb_busybox_exec_paths;
88 + if (find_applet_by_name(name) < 0)
91 + for (; *path; ++path)
92 + execve(*path, argv, envp);
97 /* just like the real execvp, but try to launch an applet named 'file' first */
98 int FAST_FUNC BB_EXECVP(const char *file, char *const argv[])
100 - if (find_applet_by_name(file) >= 0)
101 - execvp(bb_busybox_exec_path, argv);
102 + int ret = bb_execv_applet(file, argv, environ);
103 + if (errno != ENOENT)
106 return execvp(file, argv);
109 +int FAST_FUNC bb_execlp(const char *file, const char *arg, ...)
111 +#define INITIAL_ARGV_MAX 16
112 + size_t argv_max = INITIAL_ARGV_MAX;
113 + const char **argv = malloc(argv_max * sizeof (const char *));
115 + unsigned int i = 0;
118 + va_start (args, arg);
119 + while (argv[i++] != NULL) {
120 + if (i == argv_max) {
123 + nptr = realloc (argv, argv_max * sizeof (const char *));
129 + argv[i] = va_arg (args, const char *);
133 + ret = bb_execvp(file, (char *const *)argv);
140 int FAST_FUNC BB_EXECVP_or_die(char **argv)
141 --- a/libbb/messages.c
142 +++ b/libbb/messages.c
143 @@ -36,6 +36,15 @@ const char bb_msg_standard_output[] ALIG
144 const char bb_hexdigits_upcase[] ALIGN1 = "0123456789ABCDEF";
146 const char bb_busybox_exec_path[] ALIGN1 = CONFIG_BUSYBOX_EXEC_PATH;
147 +const char *bb_busybox_exec_paths[] ALIGN1 = {
151 +#ifdef CONFIG_BUSYBOX_EXEC_PATH
152 + CONFIG_BUSYBOX_EXEC_PATH,
156 const char bb_default_login_shell[] ALIGN1 = LIBBB_DEFAULT_LOGIN_SHELL;
157 /* util-linux manpage says /sbin:/bin:/usr/sbin:/usr/bin,
158 * but I want to save a few bytes here. Check libbb.h before changing! */
159 --- a/include/libbb.h
160 +++ b/include/libbb.h 2012-04-22 19:29:26.095992610 +0200
161 @@ -903,13 +903,11 @@ int exists_execable(const char *filename
162 * but it may exec busybox and call applet instead of searching PATH.
164 #if ENABLE_FEATURE_PREFER_APPLETS
165 -int BB_EXECVP(const char *file, char *const argv[]) FAST_FUNC;
166 -#define BB_EXECLP(prog,cmd,...) \
168 - if (find_applet_by_name(prog) >= 0) \
169 - execlp(bb_busybox_exec_path, cmd, __VA_ARGS__); \
170 - execlp(prog, cmd, __VA_ARGS__); \
172 +int bb_execv_applet(const char *name, char *const argv[], char *const envp[]) FAST_FUNC;
173 +int bb_execvp(const char *file, char *const argv[]) FAST_FUNC;
174 +int bb_execlp(const char *file, const char *arg, ...) FAST_FUNC;
175 +#define BB_EXECVP(prog,cmd) bb_execvp(prog,cmd)
176 +#define BB_EXECLP(prog,cmd,...) bb_execlp(prog,cmd, __VA_ARGS__)
178 #define BB_EXECVP(prog,cmd) execvp(prog,cmd)
179 #define BB_EXECLP(prog,cmd,...) execlp(prog,cmd,__VA_ARGS__)
180 @@ -1725,6 +1723,7 @@ extern const char bb_path_wtmp_file[];
182 #define bb_dev_null "/dev/null"
183 extern const char bb_busybox_exec_path[];
184 +extern const char *bb_busybox_exec_paths[];
185 /* util-linux manpage says /sbin:/bin:/usr/sbin:/usr/bin,
186 * but I want to save a few bytes here */
187 extern const char bb_PATH_root_path[]; /* "PATH=/sbin:/usr/sbin:/bin:/usr/bin" */
190 @@ -432,13 +432,10 @@ config FEATURE_PREFER_APPLETS
192 config BUSYBOX_EXEC_PATH
193 string "Path to BusyBox executable"
194 - default "/proc/self/exe"
195 + default "/bin/busybox"
197 When Busybox applets need to run other busybox applets, BusyBox
198 - sometimes needs to exec() itself. When the /proc filesystem is
199 - mounted, /proc/self/exe always points to the currently running
200 - executable. If you haven't got /proc, set this to wherever you
201 - want to run BusyBox from.
202 + sometimes needs to exec() itself.
204 # These are auto-selected by other options
206 --- a/coreutils/chroot.c
207 +++ b/coreutils/chroot.c
208 @@ -40,5 +40,7 @@ int chroot_main(int argc UNUSED_PARAM, c
209 /*argv[2] = NULL; - already is */
212 - BB_EXECVP_or_die(argv);
213 + execvp(argv[0], argv);
214 + xfunc_error_retval = (errno == ENOENT) ? 127 : 126;
215 + bb_perror_msg_and_die("can't execute '%s'", argv[0]);