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 @@ -7465,24 +7450,21 @@ shellexec(char **argv, const char *path,
32 -#if ENABLE_FEATURE_SH_STANDALONE
36 clearredir(/*drop:*/ 1);
37 envp = listvars(VEXPORT, VUNSET, /*end:*/ NULL);
38 - if (strchr(argv[0], '/') != NULL
39 -#if ENABLE_FEATURE_SH_STANDALONE
40 - || (applet_no = find_applet_by_name(argv[0])) >= 0
43 - tryexec(IF_FEATURE_SH_STANDALONE(applet_no,) argv[0], argv, envp);
44 + if (strchr(argv[0], '/') != NULL) {
45 + tryexec(argv[0], argv, envp);
48 +#if ENABLE_FEATURE_SH_STANDALONE
49 + bb_execv_applet(argv[0], argv, envp);
53 while ((cmdname = path_advance(&path, argv[0])) != NULL) {
54 if (--idx < 0 && pathopt == NULL) {
55 - tryexec(IF_FEATURE_SH_STANDALONE(-1,) cmdname, argv, envp);
56 + tryexec(cmdname, argv, envp);
57 if (errno != ENOENT && errno != ENOTDIR)
60 --- a/libbb/execable.c
61 +++ b/libbb/execable.c
69 /* check if path points to an executable file;
72 @@ -68,13 +71,60 @@ int FAST_FUNC exists_execable(const char
75 #if ENABLE_FEATURE_PREFER_APPLETS
76 +int FAST_FUNC bb_execv_applet(const char *name, char *const argv[], char *const envp[])
78 + const char **path = bb_busybox_exec_paths;
82 + if (find_applet_by_name(name) < 0)
85 + for (; *path; ++path)
86 + execve(*path, argv, envp);
91 /* just like the real execvp, but try to launch an applet named 'file' first */
92 int FAST_FUNC BB_EXECVP(const char *file, char *const argv[])
94 - if (find_applet_by_name(file) >= 0)
95 - execvp(bb_busybox_exec_path, argv);
96 + int ret = bb_execv_applet(file, argv, environ);
97 + if (errno != ENOENT)
100 return execvp(file, argv);
103 +int FAST_FUNC bb_execlp(const char *file, const char *arg, ...)
105 +#define INITIAL_ARGV_MAX 16
106 + size_t argv_max = INITIAL_ARGV_MAX;
107 + const char **argv = malloc(argv_max * sizeof (const char *));
109 + unsigned int i = 0;
112 + va_start (args, arg);
113 + while (argv[i++] != NULL) {
114 + if (i == argv_max) {
117 + nptr = realloc (argv, argv_max * sizeof (const char *));
123 + argv[i] = va_arg (args, const char *);
127 + ret = bb_execvp(file, (char *const *)argv);
134 int FAST_FUNC BB_EXECVP_or_die(char **argv)
135 --- a/libbb/messages.c
136 +++ b/libbb/messages.c
137 @@ -36,6 +36,15 @@ const char bb_msg_standard_output[] ALIG
138 const char bb_hexdigits_upcase[] ALIGN1 = "0123456789ABCDEF";
140 const char bb_busybox_exec_path[] ALIGN1 = CONFIG_BUSYBOX_EXEC_PATH;
141 +const char *bb_busybox_exec_paths[] ALIGN1 = {
145 +#ifdef CONFIG_BUSYBOX_EXEC_PATH
146 + CONFIG_BUSYBOX_EXEC_PATH,
150 const char bb_default_login_shell[] ALIGN1 = LIBBB_DEFAULT_LOGIN_SHELL;
151 /* util-linux manpage says /sbin:/bin:/usr/sbin:/usr/bin,
152 * but I want to save a few bytes here. Check libbb.h before changing! */
153 --- a/include/libbb.h
154 +++ b/include/libbb.h
155 @@ -896,13 +896,11 @@ int exists_execable(const char *filename
156 * but it may exec busybox and call applet instead of searching PATH.
158 #if ENABLE_FEATURE_PREFER_APPLETS
159 -int BB_EXECVP(const char *file, char *const argv[]) FAST_FUNC;
160 -#define BB_EXECLP(prog,cmd,...) \
162 - if (find_applet_by_name(prog) >= 0) \
163 - execlp(bb_busybox_exec_path, cmd, __VA_ARGS__); \
164 - execlp(prog, cmd, __VA_ARGS__); \
166 +int bb_execv_applet(const char *name, char *const argv[], char *const envp[]) FAST_FUNC;
167 +int bb_execvp(const char *file, char *const argv[]) FAST_FUNC;
168 +int bb_execlp(const char *file, const char *arg, ...) FAST_FUNC;
169 +#define BB_EXECVP(prog,cmd) bb_execvp(prog,cmd)
170 +#define BB_EXECLP(prog,cmd,...) bb_execlp(prog,cmd, __VA_ARGS__)
172 #define BB_EXECVP(prog,cmd) execvp(prog,cmd)
173 #define BB_EXECLP(prog,cmd,...) execlp(prog,cmd,__VA_ARGS__)
174 @@ -1683,6 +1681,7 @@ extern const char bb_path_wtmp_file[];
176 #define bb_dev_null "/dev/null"
177 extern const char bb_busybox_exec_path[];
178 +extern const char *bb_busybox_exec_paths[];
179 /* util-linux manpage says /sbin:/bin:/usr/sbin:/usr/bin,
180 * but I want to save a few bytes here */
181 extern const char bb_PATH_root_path[]; /* "PATH=/sbin:/usr/sbin:/bin:/usr/bin" */
184 @@ -431,13 +431,10 @@ config FEATURE_PREFER_APPLETS
186 config BUSYBOX_EXEC_PATH
187 string "Path to BusyBox executable"
188 - default "/proc/self/exe"
189 + default "/bin/busybox"
191 When Busybox applets need to run other busybox applets, BusyBox
192 - sometimes needs to exec() itself. When the /proc filesystem is
193 - mounted, /proc/self/exe always points to the currently running
194 - executable. If you haven't got /proc, set this to wherever you
195 - want to run BusyBox from.
196 + sometimes needs to exec() itself.
198 # These are auto-selected by other options
200 --- a/coreutils/chroot.c
201 +++ b/coreutils/chroot.c
202 @@ -41,5 +41,7 @@ int chroot_main(int argc UNUSED_PARAM, c
203 /*argv[2] = NULL; - already is */
206 - BB_EXECVP_or_die(argv);
207 + execvp(argv[0], argv);
208 + xfunc_error_retval = (errno == ENOENT) ? 127 : 126;
209 + bb_perror_msg_and_die("can't execute '%s'", argv[0]);