diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-04-14 10:09:57 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-04-14 10:09:57 +0000 |
commit | f5294e1f4c56afb377ada95a7757b28ad3c89086 (patch) | |
tree | 95a0c3632c8c2b20fa6b60f1e1a33e4fc4b24d4f | |
parent | 16abcd90aefae8bdb9f7d80a555982dba6ca59b5 (diff) | |
download | busybox-w32-f5294e1f4c56afb377ada95a7757b28ad3c89086.tar.gz busybox-w32-f5294e1f4c56afb377ada95a7757b28ad3c89086.tar.bz2 busybox-w32-f5294e1f4c56afb377ada95a7757b28ad3c89086.zip |
hush: use NOFORK applets as appropriate. Net reduction of code size.
-rw-r--r-- | applets/applets.c | 30 | ||||
-rw-r--r-- | findutils/xargs.c | 4 | ||||
-rw-r--r-- | include/libbb.h | 64 | ||||
-rw-r--r-- | libbb/vfork_daemon_rexec.c | 89 | ||||
-rw-r--r-- | shell/ash.c | 4 | ||||
-rw-r--r-- | shell/hush.c | 41 | ||||
-rw-r--r-- | shell/lash.c | 7 |
7 files changed, 125 insertions, 114 deletions
diff --git a/applets/applets.c b/applets/applets.c index 82a7eeea1..fb37fbea5 100644 --- a/applets/applets.c +++ b/applets/applets.c | |||
@@ -514,14 +514,14 @@ static void install_links(const char *busybox, int use_symbolic_links) | |||
514 | 514 | ||
515 | 515 | ||
516 | /* If we were called as "busybox..." */ | 516 | /* If we were called as "busybox..." */ |
517 | static int busybox_main(int argc, char **argv) | 517 | static int busybox_main(char **argv) |
518 | { | 518 | { |
519 | if (ENABLE_FEATURE_INSTALLER && argc > 1 && !strcmp(argv[1], "--install")) { | 519 | if (ENABLE_FEATURE_INSTALLER && argv[1] && !strcmp(argv[1], "--install")) { |
520 | int use_symbolic_links = 0; | 520 | int use_symbolic_links = 0; |
521 | char *busybox; | 521 | char *busybox; |
522 | 522 | ||
523 | /* to use symlinks, or not to use symlinks... */ | 523 | /* to use symlinks, or not to use symlinks... */ |
524 | if (argc > 2) | 524 | if (argv[2]) |
525 | if (strcmp(argv[2], "-s") == 0) | 525 | if (strcmp(argv[2], "-s") == 0) |
526 | use_symbolic_links = 1; | 526 | use_symbolic_links = 1; |
527 | 527 | ||
@@ -537,11 +537,12 @@ static int busybox_main(int argc, char **argv) | |||
537 | 537 | ||
538 | /* Deal with --help. Also print help when called with no arguments */ | 538 | /* Deal with --help. Also print help when called with no arguments */ |
539 | 539 | ||
540 | if (argc == 1 || !strcmp(argv[1], "--help") ) { | 540 | if (!argv[1] || !strcmp(argv[1], "--help") ) { |
541 | if (argc > 2) { | 541 | if (argv[2]) { |
542 | /* set name for proper "<name>: applet not found" */ | 542 | /* set name for proper "<name>: applet not found" */ |
543 | applet_name = argv[2]; | 543 | applet_name = argv[2]; |
544 | run_applet_and_exit(applet_name, 2, argv); | 544 | argv[2] = NULL; |
545 | run_applet_and_exit(applet_name, argv); | ||
545 | } else { | 546 | } else { |
546 | const struct bb_applet *a; | 547 | const struct bb_applet *a; |
547 | int col, output_width; | 548 | int col, output_width; |
@@ -582,14 +583,19 @@ static int busybox_main(int argc, char **argv) | |||
582 | } else { | 583 | } else { |
583 | /* we want "<argv[1]>: applet not found", not "busybox: ..." */ | 584 | /* we want "<argv[1]>: applet not found", not "busybox: ..." */ |
584 | applet_name = argv[1]; | 585 | applet_name = argv[1]; |
585 | run_applet_and_exit(argv[1], argc - 1, argv + 1); | 586 | run_applet_and_exit(argv[1], argv + 1); |
586 | } | 587 | } |
587 | 588 | ||
588 | bb_error_msg_and_die("applet not found"); | 589 | bb_error_msg_and_die("applet not found"); |
589 | } | 590 | } |
590 | 591 | ||
591 | void run_current_applet_and_exit(int argc, char **argv) | 592 | void run_current_applet_and_exit(char **argv) |
592 | { | 593 | { |
594 | int argc = 1; | ||
595 | |||
596 | while (argv[argc]) | ||
597 | argc++; | ||
598 | |||
593 | /* Reinit some shared global data */ | 599 | /* Reinit some shared global data */ |
594 | optind = 1; | 600 | optind = 1; |
595 | xfunc_error_retval = EXIT_FAILURE; | 601 | xfunc_error_retval = EXIT_FAILURE; |
@@ -602,13 +608,13 @@ void run_current_applet_and_exit(int argc, char **argv) | |||
602 | exit(current_applet->main(argc, argv)); | 608 | exit(current_applet->main(argc, argv)); |
603 | } | 609 | } |
604 | 610 | ||
605 | void run_applet_and_exit(const char *name, int argc, char **argv) | 611 | void run_applet_and_exit(const char *name, char **argv) |
606 | { | 612 | { |
607 | current_applet = find_applet_by_name(name); | 613 | current_applet = find_applet_by_name(name); |
608 | if (current_applet) | 614 | if (current_applet) |
609 | run_current_applet_and_exit(argc, argv); | 615 | run_current_applet_and_exit(argv); |
610 | if (!strncmp(name, "busybox", 7)) | 616 | if (!strncmp(name, "busybox", 7)) |
611 | exit(busybox_main(argc, argv)); | 617 | exit(busybox_main(argv)); |
612 | } | 618 | } |
613 | 619 | ||
614 | 620 | ||
@@ -637,6 +643,6 @@ int main(int argc, char **argv) | |||
637 | if (ENABLE_LOCALE_SUPPORT && getpid() != 1) | 643 | if (ENABLE_LOCALE_SUPPORT && getpid() != 1) |
638 | setlocale(LC_ALL, ""); | 644 | setlocale(LC_ALL, ""); |
639 | 645 | ||
640 | run_applet_and_exit(applet_name, argc, argv); | 646 | run_applet_and_exit(applet_name, argv); |
641 | bb_error_msg_and_die("applet not found"); | 647 | bb_error_msg_and_die("applet not found"); |
642 | } | 648 | } |
diff --git a/findutils/xargs.c b/findutils/xargs.c index a430e5f3d..b90f44ca4 100644 --- a/findutils/xargs.c +++ b/findutils/xargs.c | |||
@@ -176,7 +176,7 @@ set: | |||
176 | } | 176 | } |
177 | if (!eof_str_detected) { | 177 | if (!eof_str_detected) { |
178 | size_t length = (p - buf); | 178 | size_t length = (p - buf); |
179 | 179 | // TODO: smarter llist_t | |
180 | cur = xzalloc(sizeof(xlist_t) + length); | 180 | cur = xzalloc(sizeof(xlist_t) + length); |
181 | cur->data = memcpy(cur + 1, s, length); | 181 | cur->data = memcpy(cur + 1, s, length); |
182 | cur->length = length; | 182 | cur->length = length; |
@@ -247,6 +247,7 @@ static xlist_t *process_stdin(xlist_t *list_arg, | |||
247 | size_t length = (p - buf); | 247 | size_t length = (p - buf); |
248 | 248 | ||
249 | cur = xzalloc(sizeof(xlist_t) + length); | 249 | cur = xzalloc(sizeof(xlist_t) + length); |
250 | // TODO: smarter llist_t | ||
250 | cur->data = memcpy(cur + 1, s, length); | 251 | cur->data = memcpy(cur + 1, s, length); |
251 | cur->length = length; | 252 | cur->length = length; |
252 | /*cur->link = NULL;*/ | 253 | /*cur->link = NULL;*/ |
@@ -329,6 +330,7 @@ static xlist_t *process0_stdin(xlist_t *list_arg, | |||
329 | size_t length = (p - buf); | 330 | size_t length = (p - buf); |
330 | 331 | ||
331 | cur = xzalloc(sizeof(xlist_t) + length); | 332 | cur = xzalloc(sizeof(xlist_t) + length); |
333 | // TODO: smarter llist_t | ||
332 | cur->data = memcpy(cur + 1, s, length); | 334 | cur->data = memcpy(cur + 1, s, length); |
333 | cur->length = length; | 335 | cur->length = length; |
334 | /*cur->link = NULL;*/ | 336 | /*cur->link = NULL;*/ |
diff --git a/include/libbb.h b/include/libbb.h index 212b048de..77f1e0a44 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -123,35 +123,6 @@ | |||
123 | /* scary. better ideas? (but do *test* them first!) */ | 123 | /* scary. better ideas? (but do *test* them first!) */ |
124 | #define OFF_T_MAX ((off_t)~((off_t)1 << (sizeof(off_t)*8-1))) | 124 | #define OFF_T_MAX ((off_t)~((off_t)1 << (sizeof(off_t)*8-1))) |
125 | 125 | ||
126 | /* This structure defines protocol families and their handlers. */ | ||
127 | struct aftype { | ||
128 | const char *name; | ||
129 | const char *title; | ||
130 | int af; | ||
131 | int alen; | ||
132 | char *(*print) (unsigned char *); | ||
133 | const char *(*sprint) (struct sockaddr *, int numeric); | ||
134 | int (*input) (/*int type,*/ const char *bufp, struct sockaddr *); | ||
135 | void (*herror) (char *text); | ||
136 | int (*rprint) (int options); | ||
137 | int (*rinput) (int typ, int ext, char **argv); | ||
138 | |||
139 | /* may modify src */ | ||
140 | int (*getmask) (char *src, struct sockaddr * mask, char *name); | ||
141 | }; | ||
142 | |||
143 | /* This structure defines hardware protocols and their handlers. */ | ||
144 | struct hwtype { | ||
145 | const char *name; | ||
146 | const char *title; | ||
147 | int type; | ||
148 | int alen; | ||
149 | char *(*print) (unsigned char *); | ||
150 | int (*input) (const char *, struct sockaddr *); | ||
151 | int (*activate) (int fd); | ||
152 | int suppress_null_addr; | ||
153 | }; | ||
154 | |||
155 | /* Some useful definitions */ | 126 | /* Some useful definitions */ |
156 | #undef FALSE | 127 | #undef FALSE |
157 | #define FALSE ((int) 0) | 128 | #define FALSE ((int) 0) |
@@ -504,6 +475,7 @@ void clear_username_cache(void); | |||
504 | enum { USERNAME_MAX_SIZE = 16 - sizeof(int) }; | 475 | enum { USERNAME_MAX_SIZE = 16 - sizeof(int) }; |
505 | 476 | ||
506 | 477 | ||
478 | struct bb_applet; | ||
507 | int execable_file(const char *name); | 479 | int execable_file(const char *name); |
508 | char *find_execable(const char *filename); | 480 | char *find_execable(const char *filename); |
509 | int exists_execable(const char *filename); | 481 | int exists_execable(const char *filename); |
@@ -537,6 +509,8 @@ int wait_nohang(int *wstat); | |||
537 | #define wait_exitcode(w) ((w) >> 8) | 509 | #define wait_exitcode(w) ((w) >> 8) |
538 | #define wait_stopsig(w) ((w) >> 8) | 510 | #define wait_stopsig(w) ((w) >> 8) |
539 | #define wait_stopped(w) (((w) & 127) == 127) | 511 | #define wait_stopped(w) (((w) & 127) == 127) |
512 | /* Does NOT check that applet is NOFORK, just blindly runs it */ | ||
513 | int run_nofork_applet(const struct bb_applet *a, char **argv); | ||
540 | /* wait4pid(spawn(argv)) + NOFORK/NOEXEC (if configured) */ | 514 | /* wait4pid(spawn(argv)) + NOFORK/NOEXEC (if configured) */ |
541 | int spawn_and_wait(char **argv); | 515 | int spawn_and_wait(char **argv); |
542 | 516 | ||
@@ -669,6 +643,33 @@ int bbunpack(char **argv, | |||
669 | int create_icmp_socket(void); | 643 | int create_icmp_socket(void); |
670 | int create_icmp6_socket(void); | 644 | int create_icmp6_socket(void); |
671 | /* interface.c */ | 645 | /* interface.c */ |
646 | /* This structure defines protocol families and their handlers. */ | ||
647 | struct aftype { | ||
648 | const char *name; | ||
649 | const char *title; | ||
650 | int af; | ||
651 | int alen; | ||
652 | char *(*print) (unsigned char *); | ||
653 | const char *(*sprint) (struct sockaddr *, int numeric); | ||
654 | int (*input) (/*int type,*/ const char *bufp, struct sockaddr *); | ||
655 | void (*herror) (char *text); | ||
656 | int (*rprint) (int options); | ||
657 | int (*rinput) (int typ, int ext, char **argv); | ||
658 | |||
659 | /* may modify src */ | ||
660 | int (*getmask) (char *src, struct sockaddr * mask, char *name); | ||
661 | }; | ||
662 | /* This structure defines hardware protocols and their handlers. */ | ||
663 | struct hwtype { | ||
664 | const char *name; | ||
665 | const char *title; | ||
666 | int type; | ||
667 | int alen; | ||
668 | char *(*print) (unsigned char *); | ||
669 | int (*input) (const char *, struct sockaddr *); | ||
670 | int (*activate) (int fd); | ||
671 | int suppress_null_addr; | ||
672 | }; | ||
672 | extern int interface_opt_a; | 673 | extern int interface_opt_a; |
673 | int display_interfaces(char *ifname); | 674 | int display_interfaces(char *ifname); |
674 | const struct aftype *get_aftype(const char *name); | 675 | const struct aftype *get_aftype(const char *name); |
@@ -677,11 +678,10 @@ const struct hwtype *get_hwntype(int type); | |||
677 | 678 | ||
678 | 679 | ||
679 | #ifndef BUILD_INDIVIDUAL | 680 | #ifndef BUILD_INDIVIDUAL |
680 | struct bb_applet; | ||
681 | extern const struct bb_applet *find_applet_by_name(const char *name); | 681 | extern const struct bb_applet *find_applet_by_name(const char *name); |
682 | /* Returns only if applet is not found. */ | 682 | /* Returns only if applet is not found. */ |
683 | extern void run_applet_and_exit(const char *name, int argc, char **argv); | 683 | extern void run_applet_and_exit(const char *name, char **argv); |
684 | extern void run_current_applet_and_exit(int argc, char **argv) ATTRIBUTE_NORETURN; | 684 | extern void run_current_applet_and_exit(char **argv) ATTRIBUTE_NORETURN; |
685 | #endif | 685 | #endif |
686 | 686 | ||
687 | extern int match_fstype(const struct mntent *mt, const char *fstypes); | 687 | extern int match_fstype(const struct mntent *mt, const char *fstypes); |
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c index 7dbc152e2..78f3c4ad4 100644 --- a/libbb/vfork_daemon_rexec.c +++ b/libbb/vfork_daemon_rexec.c | |||
@@ -100,6 +100,52 @@ int wait_pid(int *wstat, int pid) | |||
100 | return r; | 100 | return r; |
101 | } | 101 | } |
102 | 102 | ||
103 | int run_nofork_applet(const struct bb_applet *a, char **argv) | ||
104 | { | ||
105 | int rc, argc; | ||
106 | |||
107 | /* Save some shared globals */ | ||
108 | const struct bb_applet *old_a = current_applet; | ||
109 | int old_x = xfunc_error_retval; | ||
110 | uint32_t old_m = option_mask32; | ||
111 | int old_sleep = die_sleep; | ||
112 | |||
113 | current_applet = a; | ||
114 | applet_name = a->name; | ||
115 | xfunc_error_retval = EXIT_FAILURE; | ||
116 | /*option_mask32 = 0; - not needed */ | ||
117 | /* special flag for xfunc_die(). If xfunc will "die" | ||
118 | * in NOFORK applet, xfunc_die() sees negative | ||
119 | * die_sleep and longjmp here instead. */ | ||
120 | die_sleep = -1; | ||
121 | |||
122 | argc = 1; | ||
123 | while (argv[argc]) | ||
124 | argc++; | ||
125 | |||
126 | rc = setjmp(die_jmp); | ||
127 | if (!rc) { | ||
128 | /* Some callers (xargs) | ||
129 | * need argv untouched because they free argv[i]! */ | ||
130 | char *tmp_argv[argc+1]; | ||
131 | memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0])); | ||
132 | /* Finally we can call NOFORK applet's main() */ | ||
133 | rc = a->main(argc, tmp_argv); | ||
134 | } else { /* xfunc died in NOFORK applet */ | ||
135 | /* in case they meant to return 0... */ | ||
136 | if (rc == -111) | ||
137 | rc = 0; | ||
138 | } | ||
139 | |||
140 | /* Restoring globals */ | ||
141 | current_applet = old_a; | ||
142 | applet_name = old_a->name; | ||
143 | xfunc_error_retval = old_x; | ||
144 | option_mask32 = old_m; | ||
145 | die_sleep = old_sleep; | ||
146 | return rc; | ||
147 | } | ||
148 | |||
103 | int spawn_and_wait(char **argv) | 149 | int spawn_and_wait(char **argv) |
104 | { | 150 | { |
105 | int rc; | 151 | int rc; |
@@ -111,50 +157,11 @@ int spawn_and_wait(char **argv) | |||
111 | || a->noexec /* NOEXEC trick needs fork() */ | 157 | || a->noexec /* NOEXEC trick needs fork() */ |
112 | #endif | 158 | #endif |
113 | )) { | 159 | )) { |
114 | int argc = 1; | ||
115 | char **pp = argv; | ||
116 | while (*++pp) | ||
117 | argc++; | ||
118 | #if BB_MMU | 160 | #if BB_MMU |
119 | if (a->nofork) | 161 | if (a->nofork) |
120 | #endif | 162 | #endif |
121 | { | 163 | { |
122 | /* Save some shared globals */ | 164 | return run_nofork_applet(a, argv); |
123 | const struct bb_applet *old_a = current_applet; | ||
124 | int old_x = xfunc_error_retval; | ||
125 | uint32_t old_m = option_mask32; | ||
126 | int old_sleep = die_sleep; | ||
127 | |||
128 | current_applet = a; | ||
129 | applet_name = a->name; | ||
130 | xfunc_error_retval = EXIT_FAILURE; | ||
131 | /*option_mask32 = 0; - not needed */ | ||
132 | /* special flag for xfunc_die(). If xfunc will "die" | ||
133 | * in NOFORK applet, xfunc_die() sees negative | ||
134 | * die_sleep and longjmp here instead. */ | ||
135 | die_sleep = -1; | ||
136 | |||
137 | rc = setjmp(die_jmp); | ||
138 | if (!rc) { | ||
139 | /* Some callers (xargs) | ||
140 | * need argv untouched because they free argv[i]! */ | ||
141 | char *tmp_argv[argc+1]; | ||
142 | memcpy(tmp_argv, argv, (argc+1) * sizeof(tmp_argv[0])); | ||
143 | /* Finally we can call NOFORK applet's main() */ | ||
144 | rc = a->main(argc, tmp_argv); | ||
145 | } else { /* xfunc died in NOFORK applet */ | ||
146 | /* in case they meant to return 0... */ | ||
147 | if (rc == -111) | ||
148 | rc = 0; | ||
149 | } | ||
150 | |||
151 | /* Restoring globals */ | ||
152 | current_applet = old_a; | ||
153 | applet_name = old_a->name; | ||
154 | xfunc_error_retval = old_x; | ||
155 | option_mask32 = old_m; | ||
156 | die_sleep = old_sleep; | ||
157 | return rc; | ||
158 | } | 165 | } |
159 | #if BB_MMU | 166 | #if BB_MMU |
160 | /* MMU only */ | 167 | /* MMU only */ |
@@ -165,7 +172,7 @@ int spawn_and_wait(char **argv) | |||
165 | /* child */ | 172 | /* child */ |
166 | xfunc_error_retval = EXIT_FAILURE; | 173 | xfunc_error_retval = EXIT_FAILURE; |
167 | current_applet = a; | 174 | current_applet = a; |
168 | run_current_applet_and_exit(argc, argv); | 175 | run_current_applet_and_exit(argv); |
169 | #endif | 176 | #endif |
170 | } | 177 | } |
171 | #endif /* FEATURE_PREFER_APPLETS */ | 178 | #endif /* FEATURE_PREFER_APPLETS */ |
diff --git a/shell/ash.c b/shell/ash.c index 63f039df4..90936fcc0 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
@@ -6539,10 +6539,8 @@ tryexec(char *cmd, char **argv, char **envp) | |||
6539 | a = find_applet_by_name(cmd); | 6539 | a = find_applet_by_name(cmd); |
6540 | if (a) { | 6540 | if (a) { |
6541 | if (a->noexec) { | 6541 | if (a->noexec) { |
6542 | char **c = argv; | ||
6543 | while (*c) c++; | ||
6544 | current_applet = a; | 6542 | current_applet = a; |
6545 | run_current_applet_and_exit(c - argv, argv); | 6543 | run_current_applet_and_exit(argv); |
6546 | } | 6544 | } |
6547 | /* re-exec ourselves with the new arguments */ | 6545 | /* re-exec ourselves with the new arguments */ |
6548 | execve(CONFIG_BUSYBOX_EXEC_PATH, argv, envp); | 6546 | execve(CONFIG_BUSYBOX_EXEC_PATH, argv, envp); |
diff --git a/shell/hush.c b/shell/hush.c index 035919500..9362e5916 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -765,7 +765,7 @@ static int b_check_space(o_string *o, int len) | |||
765 | * in here, such as setting a maximum string length */ | 765 | * in here, such as setting a maximum string length */ |
766 | if (o->length + len > o->maxlen) { | 766 | if (o->length + len > o->maxlen) { |
767 | char *old_data = o->data; | 767 | char *old_data = o->data; |
768 | /* assert (data == NULL || o->maxlen != 0); */ | 768 | /* assert(data == NULL || o->maxlen != 0); */ |
769 | o->maxlen += max(2*len, B_CHUNK); | 769 | o->maxlen += max(2*len, B_CHUNK); |
770 | o->data = realloc(o->data, 1 + o->maxlen); | 770 | o->data = realloc(o->data, 1 + o->maxlen); |
771 | if (o->data == NULL) { | 771 | if (o->data == NULL) { |
@@ -1113,17 +1113,10 @@ static void pseudo_exec(struct child_prog *child) | |||
1113 | * from global_argv[0], but if we are in a chroot, we may not be able | 1113 | * from global_argv[0], but if we are in a chroot, we may not be able |
1114 | * to find ourself... */ | 1114 | * to find ourself... */ |
1115 | #if ENABLE_FEATURE_SH_STANDALONE | 1115 | #if ENABLE_FEATURE_SH_STANDALONE |
1116 | { | 1116 | debug_printf("running applet %s\n", child->argv[0]); |
1117 | int argc_l; | 1117 | run_applet_and_exit(child->argv[0], child->argv); |
1118 | char** argv_l = child->argv; | 1118 | // is it ok that run_applet_and_exit() does exit(), not _exit()? |
1119 | char *name = child->argv[0]; | 1119 | // NB: IIRC on NOMMU we are after _vfork_, not fork! |
1120 | |||
1121 | /* Count argc for use in a second... */ | ||
1122 | for (argc_l = 0; *argv_l; argv_l++, argc_l++) | ||
1123 | continue; | ||
1124 | debug_printf("running applet %s\n", name); | ||
1125 | run_applet_and_exit(name, argc_l, child->argv); | ||
1126 | } | ||
1127 | #endif | 1120 | #endif |
1128 | debug_printf("exec of %s\n", child->argv[0]); | 1121 | debug_printf("exec of %s\n", child->argv[0]); |
1129 | execvp(child->argv[0], child->argv); | 1122 | execvp(child->argv[0], child->argv); |
@@ -1304,6 +1297,9 @@ static int run_pipe_real(struct pipe *pi) | |||
1304 | struct child_prog *child; | 1297 | struct child_prog *child; |
1305 | const struct built_in_command *x; | 1298 | const struct built_in_command *x; |
1306 | char *p; | 1299 | char *p; |
1300 | /* it is not always needed, but we aim to smaller code */ | ||
1301 | int squirrel[] = { -1, -1, -1 }; | ||
1302 | int rcode; | ||
1307 | 1303 | ||
1308 | nextin = 0; | 1304 | nextin = 0; |
1309 | pi->pgrp = -1; | 1305 | pi->pgrp = -1; |
@@ -1314,8 +1310,6 @@ static int run_pipe_real(struct pipe *pi) | |||
1314 | */ | 1310 | */ |
1315 | child = &(pi->progs[0]); | 1311 | child = &(pi->progs[0]); |
1316 | if (pi->num_progs == 1 && child->group && child->subshell == 0) { | 1312 | if (pi->num_progs == 1 && child->group && child->subshell == 0) { |
1317 | int squirrel[] = { -1, -1, -1 }; | ||
1318 | int rcode; | ||
1319 | debug_printf("non-subshell grouping\n"); | 1313 | debug_printf("non-subshell grouping\n"); |
1320 | setup_redirects(child, squirrel); | 1314 | setup_redirects(child, squirrel); |
1321 | /* XXX could we merge code with following builtin case, | 1315 | /* XXX could we merge code with following builtin case, |
@@ -1366,15 +1360,13 @@ static int run_pipe_real(struct pipe *pi) | |||
1366 | if (child->sp) { | 1360 | if (child->sp) { |
1367 | char *str; | 1361 | char *str; |
1368 | 1362 | ||
1369 | str = make_string((child->argv + i)); | 1363 | str = make_string(child->argv + i); |
1370 | parse_string_outer(str, FLAG_EXIT_FROM_LOOP | FLAG_REPARSING); | 1364 | parse_string_outer(str, FLAG_EXIT_FROM_LOOP | FLAG_REPARSING); |
1371 | free(str); | 1365 | free(str); |
1372 | return last_return_code; | 1366 | return last_return_code; |
1373 | } | 1367 | } |
1374 | for (x = bltins; x->cmd; x++) { | 1368 | for (x = bltins; x->cmd; x++) { |
1375 | if (strcmp(child->argv[i], x->cmd) == 0) { | 1369 | if (strcmp(child->argv[i], x->cmd) == 0) { |
1376 | int squirrel[] = { -1, -1, -1 }; | ||
1377 | int rcode; | ||
1378 | if (x->function == builtin_exec && child->argv[i+1] == NULL) { | 1370 | if (x->function == builtin_exec && child->argv[i+1] == NULL) { |
1379 | debug_printf("magic exec\n"); | 1371 | debug_printf("magic exec\n"); |
1380 | setup_redirects(child, NULL); | 1372 | setup_redirects(child, NULL); |
@@ -1393,6 +1385,17 @@ static int run_pipe_real(struct pipe *pi) | |||
1393 | return rcode; | 1385 | return rcode; |
1394 | } | 1386 | } |
1395 | } | 1387 | } |
1388 | #if ENABLE_FEATURE_SH_STANDALONE | ||
1389 | { | ||
1390 | const struct bb_applet *a = find_applet_by_name(child->argv[i]); | ||
1391 | if (a && a->nofork) { | ||
1392 | setup_redirects(child, squirrel); | ||
1393 | rcode = run_nofork_applet(a, child->argv + i); | ||
1394 | restore_redirects(squirrel); | ||
1395 | return rcode; | ||
1396 | } | ||
1397 | } | ||
1398 | #endif | ||
1396 | } | 1399 | } |
1397 | 1400 | ||
1398 | for (i = 0; i < pi->num_progs; i++) { | 1401 | for (i = 0; i < pi->num_progs; i++) { |
@@ -2587,8 +2590,8 @@ int parse_stream(o_string *dest, struct p_context *ctx, | |||
2587 | 2590 | ||
2588 | static void mapset(const char *set, int code) | 2591 | static void mapset(const char *set, int code) |
2589 | { | 2592 | { |
2590 | while (*s) | 2593 | while (*set) |
2591 | map[(unsigned char)*s++] = code; | 2594 | map[(unsigned char)*set++] = code; |
2592 | } | 2595 | } |
2593 | 2596 | ||
2594 | static void update_ifs_map(void) | 2597 | static void update_ifs_map(void) |
diff --git a/shell/lash.c b/shell/lash.c index c74684bf7..6fe2ddc76 100644 --- a/shell/lash.c +++ b/shell/lash.c | |||
@@ -1158,12 +1158,7 @@ static int pseudo_exec(struct child_prog *child) | |||
1158 | * /bin/foo is a symlink to busybox. | 1158 | * /bin/foo is a symlink to busybox. |
1159 | */ | 1159 | */ |
1160 | if (ENABLE_FEATURE_SH_STANDALONE) { | 1160 | if (ENABLE_FEATURE_SH_STANDALONE) { |
1161 | char **argv_l = child->argv; | 1161 | run_applet_and_exit(child->argv[0], child->argv); |
1162 | int argc_l; | ||
1163 | |||
1164 | for (argc_l = 0; *argv_l; argv_l++, argc_l++) | ||
1165 | continue; | ||
1166 | run_applet_and_exit(child->argv[0], argc_l, child->argv); | ||
1167 | } | 1162 | } |
1168 | 1163 | ||
1169 | execvp(child->argv[0], child->argv); | 1164 | execvp(child->argv[0], child->argv); |