diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-15 21:48:23 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-15 21:48:23 +0000 |
| commit | 27014ed5cb9f91d982426d53cd2fd8b8f923df09 (patch) | |
| tree | aa8e6f45ddd986a0e289ae931ced339c16e15918 /shell | |
| parent | c3587223c7e69212add954334d20cac7478baa69 (diff) | |
| download | busybox-w32-27014ed5cb9f91d982426d53cd2fd8b8f923df09.tar.gz busybox-w32-27014ed5cb9f91d982426d53cd2fd8b8f923df09.tar.bz2 busybox-w32-27014ed5cb9f91d982426d53cd2fd8b8f923df09.zip | |
hush: deal with a TODO: move argv_from_re_execing out of globals
function old new delta
generate_stream_from_string 156 165 +9
setup_heredoc 312 320 +8
re_execute_shell 387 391 +4
pseudo_exec_argv 129 133 +4
run_pipe 1790 1783 -7
clean_up_after_re_execute 30 - -30
------------------------------------------------------------------------------
(add/remove: 0/1 grow/shrink: 4/1 up/down: 25/-37) Total: -12 bytes
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/hush.c | 66 |
1 files changed, 39 insertions, 27 deletions
diff --git a/shell/hush.c b/shell/hush.c index b6e49db99..683f9ba32 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
| @@ -155,6 +155,7 @@ typedef struct nommu_save_t { | |||
| 155 | char **new_env; | 155 | char **new_env; |
| 156 | char **old_env; | 156 | char **old_env; |
| 157 | char **argv; | 157 | char **argv; |
| 158 | char **argv_from_re_execing; | ||
| 158 | } nommu_save_t; | 159 | } nommu_save_t; |
| 159 | #endif | 160 | #endif |
| 160 | 161 | ||
| @@ -449,7 +450,6 @@ struct globals { | |||
| 449 | char **global_argv; | 450 | char **global_argv; |
| 450 | #if !BB_MMU | 451 | #if !BB_MMU |
| 451 | char *argv0_for_re_execing; | 452 | char *argv0_for_re_execing; |
| 452 | char **argv_from_re_execing; | ||
| 453 | #endif | 453 | #endif |
| 454 | #if ENABLE_HUSH_LOOPS | 454 | #if ENABLE_HUSH_LOOPS |
| 455 | unsigned depth_break_continue; | 455 | unsigned depth_break_continue; |
| @@ -2280,9 +2280,7 @@ static char **expand_assignments(char **argv, int count) | |||
| 2280 | 2280 | ||
| 2281 | #if BB_MMU | 2281 | #if BB_MMU |
| 2282 | /* never called */ | 2282 | /* never called */ |
| 2283 | void re_execute_shell(const char *s, char *argv0, char **argv); | 2283 | void re_execute_shell(char ***to_free, const char *s, char *argv0, char **argv); |
| 2284 | |||
| 2285 | #define clean_up_after_re_execute() ((void)0) | ||
| 2286 | 2284 | ||
| 2287 | static void reset_traps_to_defaults(void) | 2285 | static void reset_traps_to_defaults(void) |
| 2288 | { | 2286 | { |
| @@ -2314,8 +2312,8 @@ static void reset_traps_to_defaults(void) | |||
| 2314 | 2312 | ||
| 2315 | #else /* !BB_MMU */ | 2313 | #else /* !BB_MMU */ |
| 2316 | 2314 | ||
| 2317 | static void re_execute_shell(const char *s, char *g_argv0, char **g_argv) NORETURN; | 2315 | static void re_execute_shell(char ***to_free, const char *s, char *g_argv0, char **g_argv) NORETURN; |
| 2318 | static void re_execute_shell(const char *s, char *g_argv0, char **g_argv) | 2316 | static void re_execute_shell(char ***to_free, const char *s, char *g_argv0, char **g_argv) |
| 2319 | { | 2317 | { |
| 2320 | char param_buf[sizeof("-$%x:%x:%x:%x") + sizeof(unsigned) * 4]; | 2318 | char param_buf[sizeof("-$%x:%x:%x:%x") + sizeof(unsigned) * 4]; |
| 2321 | char *heredoc_argv[4]; | 2319 | char *heredoc_argv[4]; |
| @@ -2357,7 +2355,7 @@ static void re_execute_shell(const char *s, char *g_argv0, char **g_argv) | |||
| 2357 | pp = g_argv; | 2355 | pp = g_argv; |
| 2358 | while (*pp++) | 2356 | while (*pp++) |
| 2359 | cnt++; | 2357 | cnt++; |
| 2360 | G.argv_from_re_execing = argv = pp = xzalloc(sizeof(argv[0]) * cnt); | 2358 | *to_free = argv = pp = xzalloc(sizeof(argv[0]) * cnt); |
| 2361 | *pp++ = (char *) G.argv0_for_re_execing; | 2359 | *pp++ = (char *) G.argv0_for_re_execing; |
| 2362 | *pp++ = param_buf; | 2360 | *pp++ = param_buf; |
| 2363 | for (cur = G.top_var; cur; cur = cur->next) { | 2361 | for (cur = G.top_var; cur; cur = cur->next) { |
| @@ -2415,16 +2413,6 @@ static void re_execute_shell(const char *s, char *g_argv0, char **g_argv) | |||
| 2415 | xfunc_error_retval = 127; | 2413 | xfunc_error_retval = 127; |
| 2416 | bb_error_msg_and_die("can't re-execute the shell"); | 2414 | bb_error_msg_and_die("can't re-execute the shell"); |
| 2417 | } | 2415 | } |
| 2418 | |||
| 2419 | static void clean_up_after_re_execute(void) | ||
| 2420 | { | ||
| 2421 | char **pp = G.argv_from_re_execing; | ||
| 2422 | if (pp) { | ||
| 2423 | /* Must match re_execute_shell's allocations (if any) */ | ||
| 2424 | free(pp); | ||
| 2425 | G.argv_from_re_execing = NULL; | ||
| 2426 | } | ||
| 2427 | } | ||
| 2428 | #endif /* !BB_MMU */ | 2416 | #endif /* !BB_MMU */ |
| 2429 | 2417 | ||
| 2430 | 2418 | ||
| @@ -2436,6 +2424,9 @@ static void setup_heredoc(struct redir_struct *redir) | |||
| 2436 | /* the _body_ of heredoc (misleading field name) */ | 2424 | /* the _body_ of heredoc (misleading field name) */ |
| 2437 | const char *heredoc = redir->rd_filename; | 2425 | const char *heredoc = redir->rd_filename; |
| 2438 | char *expanded; | 2426 | char *expanded; |
| 2427 | #if !BB_MMU | ||
| 2428 | char **to_free; | ||
| 2429 | #endif | ||
| 2439 | 2430 | ||
| 2440 | expanded = NULL; | 2431 | expanded = NULL; |
| 2441 | if (!(redir->rd_dup & HEREDOC_QUOTED)) { | 2432 | if (!(redir->rd_dup & HEREDOC_QUOTED)) { |
| @@ -2490,12 +2481,14 @@ static void setup_heredoc(struct redir_struct *redir) | |||
| 2490 | /* Delegate blocking writes to another process */ | 2481 | /* Delegate blocking writes to another process */ |
| 2491 | disable_restore_tty_pgrp_on_exit(); | 2482 | disable_restore_tty_pgrp_on_exit(); |
| 2492 | xmove_fd(pair.wr, STDOUT_FILENO); | 2483 | xmove_fd(pair.wr, STDOUT_FILENO); |
| 2493 | re_execute_shell(heredoc, NULL, NULL); | 2484 | re_execute_shell(&to_free, heredoc, NULL, NULL); |
| 2494 | #endif | 2485 | #endif |
| 2495 | } | 2486 | } |
| 2496 | /* parent */ | 2487 | /* parent */ |
| 2497 | enable_restore_tty_pgrp_on_exit(); | 2488 | enable_restore_tty_pgrp_on_exit(); |
| 2498 | clean_up_after_re_execute(); | 2489 | #if !BB_MMU |
| 2490 | free(to_free); | ||
| 2491 | #endif | ||
| 2499 | close(pair.wr); | 2492 | close(pair.wr); |
| 2500 | free(expanded); | 2493 | free(expanded); |
| 2501 | wait(NULL); /* wait till child has died */ | 2494 | wait(NULL); /* wait till child has died */ |
| @@ -2742,8 +2735,16 @@ static struct function *new_function(char *name) | |||
| 2742 | return funcp; | 2735 | return funcp; |
| 2743 | } | 2736 | } |
| 2744 | 2737 | ||
| 2745 | static void exec_function(const struct function *funcp, char **argv) NORETURN; | 2738 | #if BB_MMU |
| 2746 | static void exec_function(const struct function *funcp, char **argv) | 2739 | #define exec_function(nommu_save, funcp, argv) \ |
| 2740 | exec_function(funcp, argv) | ||
| 2741 | #endif | ||
| 2742 | static void exec_function(nommu_save_t *nommu_save, | ||
| 2743 | const struct function *funcp, | ||
| 2744 | char **argv) NORETURN; | ||
| 2745 | static void exec_function(nommu_save_t *nommu_save, | ||
| 2746 | const struct function *funcp, | ||
| 2747 | char **argv) | ||
| 2747 | { | 2748 | { |
| 2748 | # if BB_MMU | 2749 | # if BB_MMU |
| 2749 | int n = 1; | 2750 | int n = 1; |
| @@ -2758,7 +2759,10 @@ static void exec_function(const struct function *funcp, char **argv) | |||
| 2758 | fflush(NULL); | 2759 | fflush(NULL); |
| 2759 | _exit(n); | 2760 | _exit(n); |
| 2760 | # else | 2761 | # else |
| 2761 | re_execute_shell(funcp->body_as_string, G.global_argv[0], argv + 1); | 2762 | re_execute_shell(&nommu_save->argv_from_re_execing, |
| 2763 | funcp->body_as_string, | ||
| 2764 | G.global_argv[0], | ||
| 2765 | argv + 1); | ||
| 2762 | # endif | 2766 | # endif |
| 2763 | } | 2767 | } |
| 2764 | 2768 | ||
| @@ -2889,7 +2893,7 @@ static void pseudo_exec_argv(nommu_save_t *nommu_save, | |||
| 2889 | { | 2893 | { |
| 2890 | const struct function *funcp = find_function(argv[0]); | 2894 | const struct function *funcp = find_function(argv[0]); |
| 2891 | if (funcp) { | 2895 | if (funcp) { |
| 2892 | exec_function(funcp, argv); | 2896 | exec_function(nommu_save, funcp, argv); |
| 2893 | } | 2897 | } |
| 2894 | } | 2898 | } |
| 2895 | #endif | 2899 | #endif |
| @@ -2955,7 +2959,8 @@ static void pseudo_exec(nommu_save_t *nommu_save, | |||
| 2955 | * since this process is about to exit */ | 2959 | * since this process is about to exit */ |
| 2956 | _exit(rcode); | 2960 | _exit(rcode); |
| 2957 | #else | 2961 | #else |
| 2958 | re_execute_shell(command->group_as_string, | 2962 | re_execute_shell(&nommu_save->argv_from_re_execing, |
| 2963 | command->group_as_string, | ||
| 2959 | G.global_argv[0], | 2964 | G.global_argv[0], |
| 2960 | G.global_argv + 1); | 2965 | G.global_argv + 1); |
| 2961 | #endif | 2966 | #endif |
| @@ -3432,6 +3437,7 @@ static int run_pipe(struct pipe *pi) | |||
| 3432 | nommu_save.new_env = NULL; | 3437 | nommu_save.new_env = NULL; |
| 3433 | nommu_save.old_env = NULL; | 3438 | nommu_save.old_env = NULL; |
| 3434 | nommu_save.argv = NULL; | 3439 | nommu_save.argv = NULL; |
| 3440 | nommu_save.argv_from_re_execing = NULL; | ||
| 3435 | #endif | 3441 | #endif |
| 3436 | command = &(pi->cmds[i]); | 3442 | command = &(pi->cmds[i]); |
| 3437 | if (command->argv) { | 3443 | if (command->argv) { |
| @@ -3489,8 +3495,8 @@ static int run_pipe(struct pipe *pi) | |||
| 3489 | enable_restore_tty_pgrp_on_exit(); | 3495 | enable_restore_tty_pgrp_on_exit(); |
| 3490 | #if !BB_MMU | 3496 | #if !BB_MMU |
| 3491 | /* Clean up after vforked child */ | 3497 | /* Clean up after vforked child */ |
| 3492 | clean_up_after_re_execute(); | ||
| 3493 | free(nommu_save.argv); | 3498 | free(nommu_save.argv); |
| 3499 | free(nommu_save.argv_from_re_execing); | ||
| 3494 | free_strings_and_unsetenv(nommu_save.new_env, 1); | 3500 | free_strings_and_unsetenv(nommu_save.new_env, 1); |
| 3495 | putenv_all(nommu_save.old_env); | 3501 | putenv_all(nommu_save.old_env); |
| 3496 | /* Free the pointers, but the strings themselves | 3502 | /* Free the pointers, but the strings themselves |
| @@ -4657,6 +4663,9 @@ static FILE *generate_stream_from_string(const char *s) | |||
| 4657 | { | 4663 | { |
| 4658 | FILE *pf; | 4664 | FILE *pf; |
| 4659 | int pid, channel[2]; | 4665 | int pid, channel[2]; |
| 4666 | #if !BB_MMU | ||
| 4667 | char **to_free; | ||
| 4668 | #endif | ||
| 4660 | 4669 | ||
| 4661 | xpipe(channel); | 4670 | xpipe(channel); |
| 4662 | pid = BB_MMU ? fork() : vfork(); | 4671 | pid = BB_MMU ? fork() : vfork(); |
| @@ -4688,7 +4697,8 @@ static FILE *generate_stream_from_string(const char *s) | |||
| 4688 | * huge=`cat BIG` # was blocking here forever | 4697 | * huge=`cat BIG` # was blocking here forever |
| 4689 | * echo OK | 4698 | * echo OK |
| 4690 | */ | 4699 | */ |
| 4691 | re_execute_shell(s, | 4700 | re_execute_shell(&to_free, |
| 4701 | s, | ||
| 4692 | G.global_argv[0], | 4702 | G.global_argv[0], |
| 4693 | G.global_argv + 1); | 4703 | G.global_argv + 1); |
| 4694 | #endif | 4704 | #endif |
| @@ -4696,7 +4706,9 @@ static FILE *generate_stream_from_string(const char *s) | |||
| 4696 | 4706 | ||
| 4697 | /* parent */ | 4707 | /* parent */ |
| 4698 | enable_restore_tty_pgrp_on_exit(); | 4708 | enable_restore_tty_pgrp_on_exit(); |
| 4699 | clean_up_after_re_execute(); | 4709 | #if !BB_MMU |
| 4710 | free(to_free); | ||
| 4711 | #endif | ||
| 4700 | close(channel[1]); | 4712 | close(channel[1]); |
| 4701 | pf = fdopen(channel[0], "r"); | 4713 | pf = fdopen(channel[0], "r"); |
| 4702 | return pf; | 4714 | return pf; |
