3 @@ -431,13 +431,10 @@ config FEATURE_PREFER_APPLETS
5 config BUSYBOX_EXEC_PATH
6 string "Path to BusyBox executable"
7 - default "/proc/self/exe"
8 + default "/bin/busybox"
10 When Busybox applets need to run other busybox applets, BusyBox
11 - sometimes needs to exec() itself. When the /proc filesystem is
12 - mounted, /proc/self/exe always points to the currently running
13 - executable. If you haven't got /proc, set this to wherever you
14 - want to run BusyBox from.
15 + sometimes needs to exec() itself.
17 # These are auto-selected by other options
19 --- a/coreutils/chroot.c
20 +++ b/coreutils/chroot.c
21 @@ -41,5 +41,7 @@ int chroot_main(int argc UNUSED_PARAM, c
22 /*argv[2] = NULL; - already is */
25 - BB_EXECVP_or_die(argv);
26 + execvp(argv[0], argv);
27 + xfunc_error_retval = (errno == ENOENT) ? 127 : 126;
28 + bb_perror_msg_and_die("can't execute '%s'", argv[0]);
32 @@ -896,13 +896,11 @@ int exists_execable(const char *filename
33 * but it may exec busybox and call applet instead of searching PATH.
35 #if ENABLE_FEATURE_PREFER_APPLETS
36 +int bb_execv_applet(const char *name, char *const argv[], char *const envp[]) FAST_FUNC;
37 int BB_EXECVP(const char *file, char *const argv[]) FAST_FUNC;
38 -#define BB_EXECLP(prog,cmd,...) \
40 - if (find_applet_by_name(prog) >= 0) \
41 - execlp(bb_busybox_exec_path, cmd, __VA_ARGS__); \
42 - execlp(prog, cmd, __VA_ARGS__); \
44 +int bb_execlp(const char *file, const char *arg, ...) FAST_FUNC;
45 +#define BB_EXECVP(prog,cmd) bb_execvp(prog,cmd)
46 +#define BB_EXECLP(prog,cmd,...) bb_execlp(prog,cmd, __VA_ARGS__)
48 #define BB_EXECVP(prog,cmd) execvp(prog,cmd)
49 #define BB_EXECLP(prog,cmd,...) execlp(prog,cmd,__VA_ARGS__)
50 @@ -1683,6 +1681,7 @@ extern const char bb_path_wtmp_file[];
52 #define bb_dev_null "/dev/null"
53 extern const char bb_busybox_exec_path[];
54 +extern const char *bb_busybox_exec_paths[];
55 /* util-linux manpage says /sbin:/bin:/usr/sbin:/usr/bin,
56 * but I want to save a few bytes here */
57 extern const char bb_PATH_root_path[]; /* "PATH=/sbin:/usr/sbin:/bin:/usr/bin" */
58 --- a/libbb/execable.c
59 +++ b/libbb/execable.c
67 /* check if path points to an executable file;
70 @@ -68,13 +71,60 @@ int FAST_FUNC exists_execable(const char
73 #if ENABLE_FEATURE_PREFER_APPLETS
74 +int FAST_FUNC bb_execv_applet(const char *name, char *const argv[], char *const envp[])
76 + const char **path = bb_busybox_exec_paths;
80 + if (find_applet_by_name(name) < 0)
83 + for (; *path; ++path)
84 + execve(*path, argv, envp);
89 /* just like the real execvp, but try to launch an applet named 'file' first */
90 int FAST_FUNC BB_EXECVP(const char *file, char *const argv[])
92 - if (find_applet_by_name(file) >= 0)
93 - execvp(bb_busybox_exec_path, argv);
94 + int ret = bb_execv_applet(file, argv, environ);
95 + if (errno != ENOENT)
98 return execvp(file, argv);
101 +int FAST_FUNC bb_execlp(const char *file, const char *arg, ...)
103 +#define INITIAL_ARGV_MAX 16
104 + size_t argv_max = INITIAL_ARGV_MAX;
105 + const char **argv = malloc(argv_max * sizeof (const char *));
107 + unsigned int i = 0;
110 + va_start (args, arg);
111 + while (argv[i++] != NULL) {
112 + if (i == argv_max) {
115 + nptr = realloc (argv, argv_max * sizeof (const char *));
121 + argv[i] = va_arg (args, const char *);
125 + ret = bb_execvp(file, (char *const *)argv);
132 int FAST_FUNC BB_EXECVP_or_die(char **argv)
133 --- a/libbb/messages.c
134 +++ b/libbb/messages.c
135 @@ -36,6 +36,15 @@ const char bb_msg_standard_output[] ALIG
136 const char bb_hexdigits_upcase[] ALIGN1 = "0123456789ABCDEF";
138 const char bb_busybox_exec_path[] ALIGN1 = CONFIG_BUSYBOX_EXEC_PATH;
139 +const char *bb_busybox_exec_paths[] ALIGN1 = {
143 +#ifdef CONFIG_BUSYBOX_EXEC_PATH
144 + CONFIG_BUSYBOX_EXEC_PATH,
148 const char bb_default_login_shell[] ALIGN1 = LIBBB_DEFAULT_LOGIN_SHELL;
149 /* util-linux manpage says /sbin:/bin:/usr/sbin:/usr/bin,
150 * but I want to save a few bytes here. Check libbb.h before changing! */
153 @@ -7394,22 +7394,8 @@ static int builtinloc = -1; /* index
157 -tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) char *cmd, char **argv, char **envp)
158 +tryexec(char *cmd, char **argv, char **envp)
160 -#if ENABLE_FEATURE_SH_STANDALONE
161 - if (applet_no >= 0) {
162 - if (APPLET_IS_NOEXEC(applet_no)) {
166 - run_applet_no_and_exit(applet_no, argv);
168 - /* re-exec ourselves with the new arguments */
169 - execve(bb_busybox_exec_path, argv, envp);
170 - /* If they called chroot or otherwise made the binary no longer
171 - * executable, fall through */
177 @@ -7465,24 +7451,21 @@ shellexec(char **argv, const char *path,
181 -#if ENABLE_FEATURE_SH_STANDALONE
182 - int applet_no = -1;
185 clearredir(/*drop:*/ 1);
186 envp = listvars(VEXPORT, VUNSET, /*end:*/ NULL);
187 - if (strchr(argv[0], '/') != NULL
188 -#if ENABLE_FEATURE_SH_STANDALONE
189 - || (applet_no = find_applet_by_name(argv[0])) >= 0
192 - tryexec(IF_FEATURE_SH_STANDALONE(applet_no,) argv[0], argv, envp);
193 + if (strchr(argv[0], '/') != NULL) {
194 + tryexec(argv[0], argv, envp);
197 +#if ENABLE_FEATURE_SH_STANDALONE
198 + bb_execv_applet(argv[0], argv, envp);
202 while ((cmdname = path_advance(&path, argv[0])) != NULL) {
203 if (--idx < 0 && pathopt == NULL) {
204 - tryexec(IF_FEATURE_SH_STANDALONE(-1,) cmdname, argv, envp);
205 + tryexec(cmdname, argv, envp);
206 if (errno != ENOENT && errno != ENOTDIR)