1e9bc1c6165e98ca62b0e3bc448e06a0bfc50d0f
[busybox-power] / debian / patches / applets-fallback.patch
1 --- a/Config.in
2 +++ b/Config.in
3 @@ -431,13 +431,10 @@ config FEATURE_PREFER_APPLETS
4  
5  config BUSYBOX_EXEC_PATH
6         string "Path to BusyBox executable"
7 -       default "/proc/self/exe"
8 +       default "/bin/busybox"
9         help
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.
16  
17  # These are auto-selected by other options
18  
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 */
23         }
24  
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]);
29  }
30 --- a/include/libbb.h
31 +++ b/include/libbb.h
32 @@ -896,13 +896,11 @@ int exists_execable(const char *filename
33   * but it may exec busybox and call applet instead of searching PATH.
34   */
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,...) \
39 -       do { \
40 -               if (find_applet_by_name(prog) >= 0) \
41 -                       execlp(bb_busybox_exec_path, cmd, __VA_ARGS__); \
42 -               execlp(prog, cmd, __VA_ARGS__); \
43 -       } while (0)
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__)
47  #else
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[];
51  
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
60 @@ -9,6 +9,9 @@
61  
62  #include "libbb.h"
63  
64 +#include <alloca.h>
65 +#include <stdarg.h>
66 +
67  /* check if path points to an executable file;
68   * return 1 if found;
69   * return 0 otherwise;
70 @@ -68,13 +71,60 @@ int FAST_FUNC exists_execable(const char
71  }
72  
73  #if ENABLE_FEATURE_PREFER_APPLETS
74 +int FAST_FUNC bb_execv_applet(const char *name, char *const argv[], char *const envp[])
75 +{
76 +       const char **path = bb_busybox_exec_paths;
77 +
78 +       errno = ENOENT;
79 +
80 +       if (find_applet_by_name(name) < 0)
81 +               return -1;
82 +
83 +       for (; *path; ++path)
84 +               execve(*path, argv, envp);
85 +
86 +       return -1;
87 +}
88 +
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[])
91  {
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)
96 +               return ret;
97 +
98         return execvp(file, argv);
99  }
100 +
101 +int FAST_FUNC bb_execlp(const char *file, const char *arg, ...)
102 +{
103 +#define INITIAL_ARGV_MAX 16
104 +       size_t argv_max = INITIAL_ARGV_MAX;
105 +       const char **argv = malloc(argv_max * sizeof (const char *));
106 +       va_list args;
107 +       unsigned int i = 0;
108 +       int ret;
109 +
110 +       va_start (args, arg);
111 +       while (argv[i++] != NULL) {
112 +               if (i == argv_max) {
113 +                       const char **nptr;
114 +                       argv_max *= 2;
115 +                       nptr = realloc (argv, argv_max * sizeof (const char *));
116 +                       if (nptr == NULL)
117 +                               return -1;
118 +                       argv = nptr;
119 +               }
120 +
121 +               argv[i] = va_arg (args, const char *);
122 +       }
123 +       va_end (args);
124 +
125 +       ret = bb_execvp(file, (char *const *)argv);
126 +       free(argv);
127 +
128 +       return ret;
129 +}
130  #endif
131  
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";
137  
138  const char bb_busybox_exec_path[] ALIGN1 = CONFIG_BUSYBOX_EXEC_PATH;
139 +const char *bb_busybox_exec_paths[] ALIGN1 = {
140 +#ifdef __linux__
141 +       "/proc/self/exe",
142 +#endif
143 +#ifdef CONFIG_BUSYBOX_EXEC_PATH
144 +       CONFIG_BUSYBOX_EXEC_PATH,
145 +#endif
146 +       NULL
147 +};
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! */
151 --- a/shell/ash.c
152 +++ b/shell/ash.c
153 @@ -7394,22 +7394,8 @@ static int builtinloc = -1;     /* index
154  
155  
156  static void
157 -tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) char *cmd, char **argv, char **envp)
158 +tryexec(char *cmd, char **argv, char **envp)
159  {
160 -#if ENABLE_FEATURE_SH_STANDALONE
161 -       if (applet_no >= 0) {
162 -               if (APPLET_IS_NOEXEC(applet_no)) {
163 -                       clearenv();
164 -                       while (*envp)
165 -                               putenv(*envp++);
166 -                       run_applet_no_and_exit(applet_no, argv);
167 -               }
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 */
172 -       }
173 -#endif
174  
175   repeat:
176  #ifdef SYSV
177 @@ -7465,24 +7451,21 @@ shellexec(char **argv, const char *path,
178         int e;
179         char **envp;
180         int exerrno;
181 -#if ENABLE_FEATURE_SH_STANDALONE
182 -       int applet_no = -1;
183 -#endif
184  
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
190 -#endif
191 -       ) {
192 -               tryexec(IF_FEATURE_SH_STANDALONE(applet_no,) argv[0], argv, envp);
193 +       if (strchr(argv[0], '/') != NULL) {
194 +               tryexec(argv[0], argv, envp);
195                 e = errno;
196         } else {
197 +#if ENABLE_FEATURE_SH_STANDALONE
198 +               bb_execv_applet(argv[0], argv, envp);
199 +#endif
200 +
201                 e = ENOENT;
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)
207                                         e = errno;
208                         }