synchronize patches with Debian Sid
[busybox-power] / debian / patches / applets-fallback.patch
1 --- a/shell/ash.c
2 +++ b/shell/ash.c
3 @@ -7394,23 +7394,8 @@ static int builtinloc = -1;     /* index
4  
5  
6  static void
7 -tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) char *cmd, char **argv, char **envp)
8 +tryexec(char *cmd, char **argv, char **envp)
9  {
10 -#if ENABLE_FEATURE_SH_STANDALONE
11 -       if (applet_no >= 0) {
12 -               if (APPLET_IS_NOEXEC(applet_no)) {
13 -                       clearenv();
14 -                       while (*envp)
15 -                               putenv(*envp++);
16 -                       run_applet_no_and_exit(applet_no, argv);
17 -               }
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 */
22 -       }
23 -#endif
24 -
25   repeat:
26  #ifdef SYSV
27         do {
28 @@ -7465,24 +7450,21 @@ shellexec(char **argv, const char *path,
29         int e;
30         char **envp;
31         int exerrno;
32 -#if ENABLE_FEATURE_SH_STANDALONE
33 -       int applet_no = -1;
34 -#endif
35  
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
41 -#endif
42 -       ) {
43 -               tryexec(IF_FEATURE_SH_STANDALONE(applet_no,) argv[0], argv, envp);
44 +       if (strchr(argv[0], '/') != NULL) {
45 +               tryexec(argv[0], argv, envp);
46                 e = errno;
47         } else {
48 +#if ENABLE_FEATURE_SH_STANDALONE
49 +               bb_execv_applet(argv[0], argv, envp);
50 +#endif
51 +
52                 e = ENOENT;
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)
58                                         e = errno;
59                         }
60 --- a/libbb/execable.c
61 +++ b/libbb/execable.c
62 @@ -9,6 +9,9 @@
63  
64  #include "libbb.h"
65  
66 +#include <alloca.h>
67 +#include <stdarg.h>
68 +
69  /* check if path points to an executable file;
70   * return 1 if found;
71   * return 0 otherwise;
72 @@ -68,13 +71,60 @@ int FAST_FUNC exists_execable(const char
73  }
74  
75  #if ENABLE_FEATURE_PREFER_APPLETS
76 +int FAST_FUNC bb_execv_applet(const char *name, char *const argv[], char *const envp[])
77 +{
78 +       const char **path = bb_busybox_exec_paths;
79 +
80 +       errno = ENOENT;
81 +
82 +       if (find_applet_by_name(name) < 0)
83 +               return -1;
84 +
85 +       for (; *path; ++path)
86 +               execve(*path, argv, envp);
87 +
88 +       return -1;
89 +}
90 +
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[])
93  {
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)
98 +               return ret;
99 +
100         return execvp(file, argv);
101  }
102 +
103 +int FAST_FUNC bb_execlp(const char *file, const char *arg, ...)
104 +{
105 +#define INITIAL_ARGV_MAX 16
106 +       size_t argv_max = INITIAL_ARGV_MAX;
107 +       const char **argv = malloc(argv_max * sizeof (const char *));
108 +       va_list args;
109 +       unsigned int i = 0;
110 +       int ret;
111 +
112 +       va_start (args, arg);
113 +       while (argv[i++] != NULL) {
114 +               if (i == argv_max) {
115 +                       const char **nptr;
116 +                       argv_max *= 2;
117 +                       nptr = realloc (argv, argv_max * sizeof (const char *));
118 +                       if (nptr == NULL)
119 +                               return -1;
120 +                       argv = nptr;
121 +               }
122 +
123 +               argv[i] = va_arg (args, const char *);
124 +       }
125 +       va_end (args);
126 +
127 +       ret = bb_execvp(file, (char *const *)argv);
128 +       free(argv);
129 +
130 +       return ret;
131 +}
132  #endif
133  
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";
139  
140  const char bb_busybox_exec_path[] ALIGN1 = CONFIG_BUSYBOX_EXEC_PATH;
141 +const char *bb_busybox_exec_paths[] ALIGN1 = {
142 +#ifdef __linux__
143 +       "/proc/self/exe",
144 +#endif
145 +#ifdef CONFIG_BUSYBOX_EXEC_PATH
146 +       CONFIG_BUSYBOX_EXEC_PATH,
147 +#endif
148 +       NULL
149 +};
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.
157   */
158  #if ENABLE_FEATURE_PREFER_APPLETS
159 -int BB_EXECVP(const char *file, char *const argv[]) FAST_FUNC;
160 -#define BB_EXECLP(prog,cmd,...) \
161 -       do { \
162 -               if (find_applet_by_name(prog) >= 0) \
163 -                       execlp(bb_busybox_exec_path, cmd, __VA_ARGS__); \
164 -               execlp(prog, cmd, __VA_ARGS__); \
165 -       } while (0)
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__)
171  #else
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[];
175  
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" */
182 --- a/Config.in
183 +++ b/Config.in
184 @@ -431,13 +431,10 @@ config FEATURE_PREFER_APPLETS
185  
186  config BUSYBOX_EXEC_PATH
187         string "Path to BusyBox executable"
188 -       default "/proc/self/exe"
189 +       default "/bin/busybox"
190         help
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.
197  
198  # These are auto-selected by other options
199  
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 */
204         }
205  
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]);
210  }