diff options
Diffstat (limited to 'shell/hush.c')
-rw-r--r-- | shell/hush.c | 27 |
1 files changed, 17 insertions, 10 deletions
diff --git a/shell/hush.c b/shell/hush.c index 1709fd9d1..4d9e5f8c7 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -1418,6 +1418,7 @@ static void sigexit(int sig) | |||
1418 | static void hush_exit(int exitcode) NORETURN; | 1418 | static void hush_exit(int exitcode) NORETURN; |
1419 | static void hush_exit(int exitcode) | 1419 | static void hush_exit(int exitcode) |
1420 | { | 1420 | { |
1421 | fflush_all(); | ||
1421 | if (G.exiting <= 0 && G.traps && G.traps[0] && G.traps[0][0]) { | 1422 | if (G.exiting <= 0 && G.traps && G.traps[0] && G.traps[0][0]) { |
1422 | /* Prevent recursion: | 1423 | /* Prevent recursion: |
1423 | * trap "echo Hi; exit" EXIT; exit | 1424 | * trap "echo Hi; exit" EXIT; exit |
@@ -1901,7 +1902,7 @@ static void get_user_input(struct in_str *i) | |||
1901 | G.flag_SIGINT = 0; | 1902 | G.flag_SIGINT = 0; |
1902 | /* buglet: SIGINT will not make new prompt to appear _at once_, | 1903 | /* buglet: SIGINT will not make new prompt to appear _at once_, |
1903 | * only after <Enter>. (^C will work) */ | 1904 | * only after <Enter>. (^C will work) */ |
1904 | r = read_line_input(prompt_str, G.user_input_buf, CONFIG_FEATURE_EDITING_MAX_LEN-1, G.line_input_state); | 1905 | r = read_line_input(G.line_input_state, prompt_str, G.user_input_buf, CONFIG_FEATURE_EDITING_MAX_LEN-1, /*timeout*/ -1); |
1905 | /* catch *SIGINT* etc (^C is handled by read_line_input) */ | 1906 | /* catch *SIGINT* etc (^C is handled by read_line_input) */ |
1906 | check_and_run_traps(0); | 1907 | check_and_run_traps(0); |
1907 | } while (r == 0 || G.flag_SIGINT); /* repeat if ^C or SIGINT */ | 1908 | } while (r == 0 || G.flag_SIGINT); /* repeat if ^C or SIGINT */ |
@@ -6105,10 +6106,13 @@ static void exec_builtin(char ***to_free, | |||
6105 | char **argv) | 6106 | char **argv) |
6106 | { | 6107 | { |
6107 | #if BB_MMU | 6108 | #if BB_MMU |
6108 | int rcode = x->b_function(argv); | 6109 | int rcode; |
6110 | fflush_all(); | ||
6111 | rcode = x->b_function(argv); | ||
6109 | fflush_all(); | 6112 | fflush_all(); |
6110 | _exit(rcode); | 6113 | _exit(rcode); |
6111 | #else | 6114 | #else |
6115 | fflush_all(); | ||
6112 | /* On NOMMU, we must never block! | 6116 | /* On NOMMU, we must never block! |
6113 | * Example: { sleep 99 | read line; } & echo Ok | 6117 | * Example: { sleep 99 | read line; } & echo Ok |
6114 | */ | 6118 | */ |
@@ -6500,13 +6504,15 @@ static int checkjobs(struct pipe *fg_pipe) | |||
6500 | fg_pipe->alive_cmds--; | 6504 | fg_pipe->alive_cmds--; |
6501 | ex = WEXITSTATUS(status); | 6505 | ex = WEXITSTATUS(status); |
6502 | /* bash prints killer signal's name for *last* | 6506 | /* bash prints killer signal's name for *last* |
6503 | * process in pipe (prints just newline for SIGINT). | 6507 | * process in pipe (prints just newline for SIGINT/SIGPIPE). |
6504 | * Mimic this. Example: "sleep 5" + (^\ or kill -QUIT) | 6508 | * Mimic this. Example: "sleep 5" + (^\ or kill -QUIT) |
6505 | */ | 6509 | */ |
6506 | if (WIFSIGNALED(status)) { | 6510 | if (WIFSIGNALED(status)) { |
6507 | int sig = WTERMSIG(status); | 6511 | int sig = WTERMSIG(status); |
6508 | if (i == fg_pipe->num_cmds-1) | 6512 | if (i == fg_pipe->num_cmds-1) |
6509 | printf("%s\n", sig == SIGINT ? "" : get_signame(sig)); | 6513 | /* TODO: use strsignal() instead for bash compat? but that's bloat... */ |
6514 | printf("%s\n", sig == SIGINT || sig == SIGPIPE ? "" : get_signame(sig)); | ||
6515 | /* TODO: if (WCOREDUMP(status)) + " (core dumped)"; */ | ||
6510 | /* TODO: MIPS has 128 sigs (1..128), what if sig==128 here? | 6516 | /* TODO: MIPS has 128 sigs (1..128), what if sig==128 here? |
6511 | * Maybe we need to use sig | 128? */ | 6517 | * Maybe we need to use sig | 128? */ |
6512 | ex = sig + 128; | 6518 | ex = sig + 128; |
@@ -6615,7 +6621,7 @@ static int checkjobs_and_fg_shell(struct pipe *fg_pipe) | |||
6615 | * cmd ; ... { list } ; ... | 6621 | * cmd ; ... { list } ; ... |
6616 | * cmd && ... { list } && ... | 6622 | * cmd && ... { list } && ... |
6617 | * cmd || ... { list } || ... | 6623 | * cmd || ... { list } || ... |
6618 | * If it is, then we can run cmd as a builtin, NOFORK [do we do this?], | 6624 | * If it is, then we can run cmd as a builtin, NOFORK, |
6619 | * or (if SH_STANDALONE) an applet, and we can run the { list } | 6625 | * or (if SH_STANDALONE) an applet, and we can run the { list } |
6620 | * with run_list. If it isn't one of these, we fork and exec cmd. | 6626 | * with run_list. If it isn't one of these, we fork and exec cmd. |
6621 | * | 6627 | * |
@@ -6797,13 +6803,12 @@ static NOINLINE int run_pipe(struct pipe *pi) | |||
6797 | } | 6803 | } |
6798 | 6804 | ||
6799 | /* Expand the rest into (possibly) many strings each */ | 6805 | /* Expand the rest into (possibly) many strings each */ |
6800 | if (0) {} | ||
6801 | #if ENABLE_HUSH_BASH_COMPAT | 6806 | #if ENABLE_HUSH_BASH_COMPAT |
6802 | else if (command->cmd_type == CMD_SINGLEWORD_NOGLOB) { | 6807 | if (command->cmd_type == CMD_SINGLEWORD_NOGLOB) { |
6803 | argv_expanded = expand_strvec_to_strvec_singleword_noglob(argv + command->assignment_cnt); | 6808 | argv_expanded = expand_strvec_to_strvec_singleword_noglob(argv + command->assignment_cnt); |
6804 | } | 6809 | } else |
6805 | #endif | 6810 | #endif |
6806 | else { | 6811 | { |
6807 | argv_expanded = expand_strvec_to_strvec(argv + command->assignment_cnt); | 6812 | argv_expanded = expand_strvec_to_strvec(argv + command->assignment_cnt); |
6808 | } | 6813 | } |
6809 | 6814 | ||
@@ -6833,6 +6838,7 @@ static NOINLINE int run_pipe(struct pipe *pi) | |||
6833 | if (!funcp) { | 6838 | if (!funcp) { |
6834 | debug_printf_exec(": builtin '%s' '%s'...\n", | 6839 | debug_printf_exec(": builtin '%s' '%s'...\n", |
6835 | x->b_cmd, argv_expanded[1]); | 6840 | x->b_cmd, argv_expanded[1]); |
6841 | fflush_all(); | ||
6836 | rcode = x->b_function(argv_expanded) & 0xff; | 6842 | rcode = x->b_function(argv_expanded) & 0xff; |
6837 | fflush_all(); | 6843 | fflush_all(); |
6838 | } | 6844 | } |
@@ -6865,7 +6871,7 @@ static NOINLINE int run_pipe(struct pipe *pi) | |||
6865 | return rcode; | 6871 | return rcode; |
6866 | } | 6872 | } |
6867 | 6873 | ||
6868 | if (ENABLE_FEATURE_SH_STANDALONE) { | 6874 | if (ENABLE_FEATURE_SH_NOFORK) { |
6869 | int n = find_applet_by_name(argv_expanded[0]); | 6875 | int n = find_applet_by_name(argv_expanded[0]); |
6870 | if (n >= 0 && APPLET_IS_NOFORK(n)) { | 6876 | if (n >= 0 && APPLET_IS_NOFORK(n)) { |
6871 | rcode = redirect_and_varexp_helper(&new_env, &old_vars, command, squirrel, argv_expanded); | 6877 | rcode = redirect_and_varexp_helper(&new_env, &old_vars, command, squirrel, argv_expanded); |
@@ -7642,6 +7648,7 @@ int hush_main(int argc, char **argv) | |||
7642 | G.global_argc -= builtin_argc; /* skip [BARGV...] "" */ | 7648 | G.global_argc -= builtin_argc; /* skip [BARGV...] "" */ |
7643 | G.global_argv += builtin_argc; | 7649 | G.global_argv += builtin_argc; |
7644 | G.global_argv[-1] = NULL; /* replace "" */ | 7650 | G.global_argv[-1] = NULL; /* replace "" */ |
7651 | fflush_all(); | ||
7645 | G.last_exitcode = x->b_function(argv + optind - 1); | 7652 | G.last_exitcode = x->b_function(argv + optind - 1); |
7646 | } | 7653 | } |
7647 | goto final_return; | 7654 | goto final_return; |