mirror of https://github.com/mirror/busybox.git
hush: use NOFORK applets as appropriate. Net reduction of code size.
parent
16abcd90ae
commit
f5294e1f4c
|
@ -514,14 +514,14 @@ static void install_links(const char *busybox, int use_symbolic_links)
|
||||||
|
|
||||||
|
|
||||||
/* If we were called as "busybox..." */
|
/* If we were called as "busybox..." */
|
||||||
static int busybox_main(int argc, char **argv)
|
static int busybox_main(char **argv)
|
||||||
{
|
{
|
||||||
if (ENABLE_FEATURE_INSTALLER && argc > 1 && !strcmp(argv[1], "--install")) {
|
if (ENABLE_FEATURE_INSTALLER && argv[1] && !strcmp(argv[1], "--install")) {
|
||||||
int use_symbolic_links = 0;
|
int use_symbolic_links = 0;
|
||||||
char *busybox;
|
char *busybox;
|
||||||
|
|
||||||
/* to use symlinks, or not to use symlinks... */
|
/* to use symlinks, or not to use symlinks... */
|
||||||
if (argc > 2)
|
if (argv[2])
|
||||||
if (strcmp(argv[2], "-s") == 0)
|
if (strcmp(argv[2], "-s") == 0)
|
||||||
use_symbolic_links = 1;
|
use_symbolic_links = 1;
|
||||||
|
|
||||||
|
@ -537,11 +537,12 @@ static int busybox_main(int argc, char **argv)
|
||||||
|
|
||||||
/* Deal with --help. Also print help when called with no arguments */
|
/* Deal with --help. Also print help when called with no arguments */
|
||||||
|
|
||||||
if (argc == 1 || !strcmp(argv[1], "--help") ) {
|
if (!argv[1] || !strcmp(argv[1], "--help") ) {
|
||||||
if (argc > 2) {
|
if (argv[2]) {
|
||||||
/* set name for proper "<name>: applet not found" */
|
/* set name for proper "<name>: applet not found" */
|
||||||
applet_name = argv[2];
|
applet_name = argv[2];
|
||||||
run_applet_and_exit(applet_name, 2, argv);
|
argv[2] = NULL;
|
||||||
|
run_applet_and_exit(applet_name, argv);
|
||||||
} else {
|
} else {
|
||||||
const struct bb_applet *a;
|
const struct bb_applet *a;
|
||||||
int col, output_width;
|
int col, output_width;
|
||||||
|
@ -582,14 +583,19 @@ static int busybox_main(int argc, char **argv)
|
||||||
} else {
|
} else {
|
||||||
/* we want "<argv[1]>: applet not found", not "busybox: ..." */
|
/* we want "<argv[1]>: applet not found", not "busybox: ..." */
|
||||||
applet_name = argv[1];
|
applet_name = argv[1];
|
||||||
run_applet_and_exit(argv[1], argc - 1, argv + 1);
|
run_applet_and_exit(argv[1], argv + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bb_error_msg_and_die("applet not found");
|
bb_error_msg_and_die("applet not found");
|
||||||
}
|
}
|
||||||
|
|
||||||
void run_current_applet_and_exit(int argc, char **argv)
|
void run_current_applet_and_exit(char **argv)
|
||||||
{
|
{
|
||||||
|
int argc = 1;
|
||||||
|
|
||||||
|
while (argv[argc])
|
||||||
|
argc++;
|
||||||
|
|
||||||
/* Reinit some shared global data */
|
/* Reinit some shared global data */
|
||||||
optind = 1;
|
optind = 1;
|
||||||
xfunc_error_retval = EXIT_FAILURE;
|
xfunc_error_retval = EXIT_FAILURE;
|
||||||
|
@ -602,13 +608,13 @@ void run_current_applet_and_exit(int argc, char **argv)
|
||||||
exit(current_applet->main(argc, argv));
|
exit(current_applet->main(argc, argv));
|
||||||
}
|
}
|
||||||
|
|
||||||
void run_applet_and_exit(const char *name, int argc, char **argv)
|
void run_applet_and_exit(const char *name, char **argv)
|
||||||
{
|
{
|
||||||
current_applet = find_applet_by_name(name);
|
current_applet = find_applet_by_name(name);
|
||||||
if (current_applet)
|
if (current_applet)
|
||||||
run_current_applet_and_exit(argc, argv);
|
run_current_applet_and_exit(argv);
|
||||||
if (!strncmp(name, "busybox", 7))
|
if (!strncmp(name, "busybox", 7))
|
||||||
exit(busybox_main(argc, argv));
|
exit(busybox_main(argv));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -637,6 +643,6 @@ int main(int argc, char **argv)
|
||||||
if (ENABLE_LOCALE_SUPPORT && getpid() != 1)
|
if (ENABLE_LOCALE_SUPPORT && getpid() != 1)
|
||||||
setlocale(LC_ALL, "");
|
setlocale(LC_ALL, "");
|
||||||
|
|
||||||
run_applet_and_exit(applet_name, argc, argv);
|
run_applet_and_exit(applet_name, argv);
|
||||||
bb_error_msg_and_die("applet not found");
|
bb_error_msg_and_die("applet not found");
|
||||||
}
|
}
|
||||||
|
|
|
@ -176,7 +176,7 @@ set:
|
||||||
}
|
}
|
||||||
if (!eof_str_detected) {
|
if (!eof_str_detected) {
|
||||||
size_t length = (p - buf);
|
size_t length = (p - buf);
|
||||||
|
// TODO: smarter llist_t
|
||||||
cur = xzalloc(sizeof(xlist_t) + length);
|
cur = xzalloc(sizeof(xlist_t) + length);
|
||||||
cur->data = memcpy(cur + 1, s, length);
|
cur->data = memcpy(cur + 1, s, length);
|
||||||
cur->length = length;
|
cur->length = length;
|
||||||
|
@ -247,6 +247,7 @@ static xlist_t *process_stdin(xlist_t *list_arg,
|
||||||
size_t length = (p - buf);
|
size_t length = (p - buf);
|
||||||
|
|
||||||
cur = xzalloc(sizeof(xlist_t) + length);
|
cur = xzalloc(sizeof(xlist_t) + length);
|
||||||
|
// TODO: smarter llist_t
|
||||||
cur->data = memcpy(cur + 1, s, length);
|
cur->data = memcpy(cur + 1, s, length);
|
||||||
cur->length = length;
|
cur->length = length;
|
||||||
/*cur->link = NULL;*/
|
/*cur->link = NULL;*/
|
||||||
|
@ -329,6 +330,7 @@ static xlist_t *process0_stdin(xlist_t *list_arg,
|
||||||
size_t length = (p - buf);
|
size_t length = (p - buf);
|
||||||
|
|
||||||
cur = xzalloc(sizeof(xlist_t) + length);
|
cur = xzalloc(sizeof(xlist_t) + length);
|
||||||
|
// TODO: smarter llist_t
|
||||||
cur->data = memcpy(cur + 1, s, length);
|
cur->data = memcpy(cur + 1, s, length);
|
||||||
cur->length = length;
|
cur->length = length;
|
||||||
/*cur->link = NULL;*/
|
/*cur->link = NULL;*/
|
||||||
|
|
|
@ -123,35 +123,6 @@
|
||||||
/* scary. better ideas? (but do *test* them first!) */
|
/* scary. better ideas? (but do *test* them first!) */
|
||||||
#define OFF_T_MAX ((off_t)~((off_t)1 << (sizeof(off_t)*8-1)))
|
#define OFF_T_MAX ((off_t)~((off_t)1 << (sizeof(off_t)*8-1)))
|
||||||
|
|
||||||
/* This structure defines protocol families and their handlers. */
|
|
||||||
struct aftype {
|
|
||||||
const char *name;
|
|
||||||
const char *title;
|
|
||||||
int af;
|
|
||||||
int alen;
|
|
||||||
char *(*print) (unsigned char *);
|
|
||||||
const char *(*sprint) (struct sockaddr *, int numeric);
|
|
||||||
int (*input) (/*int type,*/ const char *bufp, struct sockaddr *);
|
|
||||||
void (*herror) (char *text);
|
|
||||||
int (*rprint) (int options);
|
|
||||||
int (*rinput) (int typ, int ext, char **argv);
|
|
||||||
|
|
||||||
/* may modify src */
|
|
||||||
int (*getmask) (char *src, struct sockaddr * mask, char *name);
|
|
||||||
};
|
|
||||||
|
|
||||||
/* This structure defines hardware protocols and their handlers. */
|
|
||||||
struct hwtype {
|
|
||||||
const char *name;
|
|
||||||
const char *title;
|
|
||||||
int type;
|
|
||||||
int alen;
|
|
||||||
char *(*print) (unsigned char *);
|
|
||||||
int (*input) (const char *, struct sockaddr *);
|
|
||||||
int (*activate) (int fd);
|
|
||||||
int suppress_null_addr;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Some useful definitions */
|
/* Some useful definitions */
|
||||||
#undef FALSE
|
#undef FALSE
|
||||||
#define FALSE ((int) 0)
|
#define FALSE ((int) 0)
|
||||||
|
@ -504,6 +475,7 @@ void clear_username_cache(void);
|
||||||
enum { USERNAME_MAX_SIZE = 16 - sizeof(int) };
|
enum { USERNAME_MAX_SIZE = 16 - sizeof(int) };
|
||||||
|
|
||||||
|
|
||||||
|
struct bb_applet;
|
||||||
int execable_file(const char *name);
|
int execable_file(const char *name);
|
||||||
char *find_execable(const char *filename);
|
char *find_execable(const char *filename);
|
||||||
int exists_execable(const char *filename);
|
int exists_execable(const char *filename);
|
||||||
|
@ -537,6 +509,8 @@ int wait_nohang(int *wstat);
|
||||||
#define wait_exitcode(w) ((w) >> 8)
|
#define wait_exitcode(w) ((w) >> 8)
|
||||||
#define wait_stopsig(w) ((w) >> 8)
|
#define wait_stopsig(w) ((w) >> 8)
|
||||||
#define wait_stopped(w) (((w) & 127) == 127)
|
#define wait_stopped(w) (((w) & 127) == 127)
|
||||||
|
/* Does NOT check that applet is NOFORK, just blindly runs it */
|
||||||
|
int run_nofork_applet(const struct bb_applet *a, char **argv);
|
||||||
/* wait4pid(spawn(argv)) + NOFORK/NOEXEC (if configured) */
|
/* wait4pid(spawn(argv)) + NOFORK/NOEXEC (if configured) */
|
||||||
int spawn_and_wait(char **argv);
|
int spawn_and_wait(char **argv);
|
||||||
|
|
||||||
|
@ -669,6 +643,33 @@ int bbunpack(char **argv,
|
||||||
int create_icmp_socket(void);
|
int create_icmp_socket(void);
|
||||||
int create_icmp6_socket(void);
|
int create_icmp6_socket(void);
|
||||||
/* interface.c */
|
/* interface.c */
|
||||||
|
/* This structure defines protocol families and their handlers. */
|
||||||
|
struct aftype {
|
||||||
|
const char *name;
|
||||||
|
const char *title;
|
||||||
|
int af;
|
||||||
|
int alen;
|
||||||
|
char *(*print) (unsigned char *);
|
||||||
|
const char *(*sprint) (struct sockaddr *, int numeric);
|
||||||
|
int (*input) (/*int type,*/ const char *bufp, struct sockaddr *);
|
||||||
|
void (*herror) (char *text);
|
||||||
|
int (*rprint) (int options);
|
||||||
|
int (*rinput) (int typ, int ext, char **argv);
|
||||||
|
|
||||||
|
/* may modify src */
|
||||||
|
int (*getmask) (char *src, struct sockaddr * mask, char *name);
|
||||||
|
};
|
||||||
|
/* This structure defines hardware protocols and their handlers. */
|
||||||
|
struct hwtype {
|
||||||
|
const char *name;
|
||||||
|
const char *title;
|
||||||
|
int type;
|
||||||
|
int alen;
|
||||||
|
char *(*print) (unsigned char *);
|
||||||
|
int (*input) (const char *, struct sockaddr *);
|
||||||
|
int (*activate) (int fd);
|
||||||
|
int suppress_null_addr;
|
||||||
|
};
|
||||||
extern int interface_opt_a;
|
extern int interface_opt_a;
|
||||||
int display_interfaces(char *ifname);
|
int display_interfaces(char *ifname);
|
||||||
const struct aftype *get_aftype(const char *name);
|
const struct aftype *get_aftype(const char *name);
|
||||||
|
@ -677,11 +678,10 @@ const struct hwtype *get_hwntype(int type);
|
||||||
|
|
||||||
|
|
||||||
#ifndef BUILD_INDIVIDUAL
|
#ifndef BUILD_INDIVIDUAL
|
||||||
struct bb_applet;
|
|
||||||
extern const struct bb_applet *find_applet_by_name(const char *name);
|
extern const struct bb_applet *find_applet_by_name(const char *name);
|
||||||
/* Returns only if applet is not found. */
|
/* Returns only if applet is not found. */
|
||||||
extern void run_applet_and_exit(const char *name, int argc, char **argv);
|
extern void run_applet_and_exit(const char *name, char **argv);
|
||||||
extern void run_current_applet_and_exit(int argc, char **argv) ATTRIBUTE_NORETURN;
|
extern void run_current_applet_and_exit(char **argv) ATTRIBUTE_NORETURN;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern int match_fstype(const struct mntent *mt, const char *fstypes);
|
extern int match_fstype(const struct mntent *mt, const char *fstypes);
|
||||||
|
|
|
@ -100,25 +100,10 @@ int wait_pid(int *wstat, int pid)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int spawn_and_wait(char **argv)
|
int run_nofork_applet(const struct bb_applet *a, char **argv)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc, argc;
|
||||||
#if ENABLE_FEATURE_PREFER_APPLETS
|
|
||||||
const struct bb_applet *a = find_applet_by_name(argv[0]);
|
|
||||||
|
|
||||||
if (a && (a->nofork
|
|
||||||
#if BB_MMU
|
|
||||||
|| a->noexec /* NOEXEC trick needs fork() */
|
|
||||||
#endif
|
|
||||||
)) {
|
|
||||||
int argc = 1;
|
|
||||||
char **pp = argv;
|
|
||||||
while (*++pp)
|
|
||||||
argc++;
|
|
||||||
#if BB_MMU
|
|
||||||
if (a->nofork)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
/* Save some shared globals */
|
/* Save some shared globals */
|
||||||
const struct bb_applet *old_a = current_applet;
|
const struct bb_applet *old_a = current_applet;
|
||||||
int old_x = xfunc_error_retval;
|
int old_x = xfunc_error_retval;
|
||||||
|
@ -134,6 +119,10 @@ int spawn_and_wait(char **argv)
|
||||||
* die_sleep and longjmp here instead. */
|
* die_sleep and longjmp here instead. */
|
||||||
die_sleep = -1;
|
die_sleep = -1;
|
||||||
|
|
||||||
|
argc = 1;
|
||||||
|
while (argv[argc])
|
||||||
|
argc++;
|
||||||
|
|
||||||
rc = setjmp(die_jmp);
|
rc = setjmp(die_jmp);
|
||||||
if (!rc) {
|
if (!rc) {
|
||||||
/* Some callers (xargs)
|
/* Some callers (xargs)
|
||||||
|
@ -155,6 +144,24 @@ int spawn_and_wait(char **argv)
|
||||||
option_mask32 = old_m;
|
option_mask32 = old_m;
|
||||||
die_sleep = old_sleep;
|
die_sleep = old_sleep;
|
||||||
return rc;
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int spawn_and_wait(char **argv)
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
#if ENABLE_FEATURE_PREFER_APPLETS
|
||||||
|
const struct bb_applet *a = find_applet_by_name(argv[0]);
|
||||||
|
|
||||||
|
if (a && (a->nofork
|
||||||
|
#if BB_MMU
|
||||||
|
|| a->noexec /* NOEXEC trick needs fork() */
|
||||||
|
#endif
|
||||||
|
)) {
|
||||||
|
#if BB_MMU
|
||||||
|
if (a->nofork)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
return run_nofork_applet(a, argv);
|
||||||
}
|
}
|
||||||
#if BB_MMU
|
#if BB_MMU
|
||||||
/* MMU only */
|
/* MMU only */
|
||||||
|
@ -165,7 +172,7 @@ int spawn_and_wait(char **argv)
|
||||||
/* child */
|
/* child */
|
||||||
xfunc_error_retval = EXIT_FAILURE;
|
xfunc_error_retval = EXIT_FAILURE;
|
||||||
current_applet = a;
|
current_applet = a;
|
||||||
run_current_applet_and_exit(argc, argv);
|
run_current_applet_and_exit(argv);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif /* FEATURE_PREFER_APPLETS */
|
#endif /* FEATURE_PREFER_APPLETS */
|
||||||
|
|
|
@ -6539,10 +6539,8 @@ tryexec(char *cmd, char **argv, char **envp)
|
||||||
a = find_applet_by_name(cmd);
|
a = find_applet_by_name(cmd);
|
||||||
if (a) {
|
if (a) {
|
||||||
if (a->noexec) {
|
if (a->noexec) {
|
||||||
char **c = argv;
|
|
||||||
while (*c) c++;
|
|
||||||
current_applet = a;
|
current_applet = a;
|
||||||
run_current_applet_and_exit(c - argv, argv);
|
run_current_applet_and_exit(argv);
|
||||||
}
|
}
|
||||||
/* re-exec ourselves with the new arguments */
|
/* re-exec ourselves with the new arguments */
|
||||||
execve(CONFIG_BUSYBOX_EXEC_PATH, argv, envp);
|
execve(CONFIG_BUSYBOX_EXEC_PATH, argv, envp);
|
||||||
|
|
41
shell/hush.c
41
shell/hush.c
|
@ -765,7 +765,7 @@ static int b_check_space(o_string *o, int len)
|
||||||
* in here, such as setting a maximum string length */
|
* in here, such as setting a maximum string length */
|
||||||
if (o->length + len > o->maxlen) {
|
if (o->length + len > o->maxlen) {
|
||||||
char *old_data = o->data;
|
char *old_data = o->data;
|
||||||
/* assert (data == NULL || o->maxlen != 0); */
|
/* assert(data == NULL || o->maxlen != 0); */
|
||||||
o->maxlen += max(2*len, B_CHUNK);
|
o->maxlen += max(2*len, B_CHUNK);
|
||||||
o->data = realloc(o->data, 1 + o->maxlen);
|
o->data = realloc(o->data, 1 + o->maxlen);
|
||||||
if (o->data == NULL) {
|
if (o->data == NULL) {
|
||||||
|
@ -1113,17 +1113,10 @@ static void pseudo_exec(struct child_prog *child)
|
||||||
* from global_argv[0], but if we are in a chroot, we may not be able
|
* from global_argv[0], but if we are in a chroot, we may not be able
|
||||||
* to find ourself... */
|
* to find ourself... */
|
||||||
#if ENABLE_FEATURE_SH_STANDALONE
|
#if ENABLE_FEATURE_SH_STANDALONE
|
||||||
{
|
debug_printf("running applet %s\n", child->argv[0]);
|
||||||
int argc_l;
|
run_applet_and_exit(child->argv[0], child->argv);
|
||||||
char** argv_l = child->argv;
|
// is it ok that run_applet_and_exit() does exit(), not _exit()?
|
||||||
char *name = child->argv[0];
|
// NB: IIRC on NOMMU we are after _vfork_, not fork!
|
||||||
|
|
||||||
/* Count argc for use in a second... */
|
|
||||||
for (argc_l = 0; *argv_l; argv_l++, argc_l++)
|
|
||||||
continue;
|
|
||||||
debug_printf("running applet %s\n", name);
|
|
||||||
run_applet_and_exit(name, argc_l, child->argv);
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
debug_printf("exec of %s\n", child->argv[0]);
|
debug_printf("exec of %s\n", child->argv[0]);
|
||||||
execvp(child->argv[0], child->argv);
|
execvp(child->argv[0], child->argv);
|
||||||
|
@ -1304,6 +1297,9 @@ static int run_pipe_real(struct pipe *pi)
|
||||||
struct child_prog *child;
|
struct child_prog *child;
|
||||||
const struct built_in_command *x;
|
const struct built_in_command *x;
|
||||||
char *p;
|
char *p;
|
||||||
|
/* it is not always needed, but we aim to smaller code */
|
||||||
|
int squirrel[] = { -1, -1, -1 };
|
||||||
|
int rcode;
|
||||||
|
|
||||||
nextin = 0;
|
nextin = 0;
|
||||||
pi->pgrp = -1;
|
pi->pgrp = -1;
|
||||||
|
@ -1314,8 +1310,6 @@ static int run_pipe_real(struct pipe *pi)
|
||||||
*/
|
*/
|
||||||
child = &(pi->progs[0]);
|
child = &(pi->progs[0]);
|
||||||
if (pi->num_progs == 1 && child->group && child->subshell == 0) {
|
if (pi->num_progs == 1 && child->group && child->subshell == 0) {
|
||||||
int squirrel[] = { -1, -1, -1 };
|
|
||||||
int rcode;
|
|
||||||
debug_printf("non-subshell grouping\n");
|
debug_printf("non-subshell grouping\n");
|
||||||
setup_redirects(child, squirrel);
|
setup_redirects(child, squirrel);
|
||||||
/* XXX could we merge code with following builtin case,
|
/* XXX could we merge code with following builtin case,
|
||||||
|
@ -1366,15 +1360,13 @@ static int run_pipe_real(struct pipe *pi)
|
||||||
if (child->sp) {
|
if (child->sp) {
|
||||||
char *str;
|
char *str;
|
||||||
|
|
||||||
str = make_string((child->argv + i));
|
str = make_string(child->argv + i);
|
||||||
parse_string_outer(str, FLAG_EXIT_FROM_LOOP | FLAG_REPARSING);
|
parse_string_outer(str, FLAG_EXIT_FROM_LOOP | FLAG_REPARSING);
|
||||||
free(str);
|
free(str);
|
||||||
return last_return_code;
|
return last_return_code;
|
||||||
}
|
}
|
||||||
for (x = bltins; x->cmd; x++) {
|
for (x = bltins; x->cmd; x++) {
|
||||||
if (strcmp(child->argv[i], x->cmd) == 0) {
|
if (strcmp(child->argv[i], x->cmd) == 0) {
|
||||||
int squirrel[] = { -1, -1, -1 };
|
|
||||||
int rcode;
|
|
||||||
if (x->function == builtin_exec && child->argv[i+1] == NULL) {
|
if (x->function == builtin_exec && child->argv[i+1] == NULL) {
|
||||||
debug_printf("magic exec\n");
|
debug_printf("magic exec\n");
|
||||||
setup_redirects(child, NULL);
|
setup_redirects(child, NULL);
|
||||||
|
@ -1393,6 +1385,17 @@ static int run_pipe_real(struct pipe *pi)
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if ENABLE_FEATURE_SH_STANDALONE
|
||||||
|
{
|
||||||
|
const struct bb_applet *a = find_applet_by_name(child->argv[i]);
|
||||||
|
if (a && a->nofork) {
|
||||||
|
setup_redirects(child, squirrel);
|
||||||
|
rcode = run_nofork_applet(a, child->argv + i);
|
||||||
|
restore_redirects(squirrel);
|
||||||
|
return rcode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < pi->num_progs; i++) {
|
for (i = 0; i < pi->num_progs; i++) {
|
||||||
|
@ -2587,8 +2590,8 @@ int parse_stream(o_string *dest, struct p_context *ctx,
|
||||||
|
|
||||||
static void mapset(const char *set, int code)
|
static void mapset(const char *set, int code)
|
||||||
{
|
{
|
||||||
while (*s)
|
while (*set)
|
||||||
map[(unsigned char)*s++] = code;
|
map[(unsigned char)*set++] = code;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_ifs_map(void)
|
static void update_ifs_map(void)
|
||||||
|
|
|
@ -1158,12 +1158,7 @@ static int pseudo_exec(struct child_prog *child)
|
||||||
* /bin/foo is a symlink to busybox.
|
* /bin/foo is a symlink to busybox.
|
||||||
*/
|
*/
|
||||||
if (ENABLE_FEATURE_SH_STANDALONE) {
|
if (ENABLE_FEATURE_SH_STANDALONE) {
|
||||||
char **argv_l = child->argv;
|
run_applet_and_exit(child->argv[0], child->argv);
|
||||||
int argc_l;
|
|
||||||
|
|
||||||
for (argc_l = 0; *argv_l; argv_l++, argc_l++)
|
|
||||||
continue;
|
|
||||||
run_applet_and_exit(child->argv[0], argc_l, child->argv);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
execvp(child->argv[0], child->argv);
|
execvp(child->argv[0], child->argv);
|
||||||
|
|
Loading…
Reference in New Issue