diff options
| author | Ron Yorston <rmy@pobox.com> | 2013-08-27 16:10:53 +0100 |
|---|---|---|
| committer | Ron Yorston <rmy@pobox.com> | 2013-08-27 16:10:53 +0100 |
| commit | 3fd34651ea72ea1c335d3170f234cb0517fd897f (patch) | |
| tree | 36e8fc40cffd464ffda4759020777dd3ca23ca31 /shell | |
| parent | e3ac39098326de084a805d0dd31db9666b734f20 (diff) | |
| parent | d6ae4fb446daedfe3073d67be655942e9fa7eb18 (diff) | |
| download | busybox-w32-3fd34651ea72ea1c335d3170f234cb0517fd897f.tar.gz busybox-w32-3fd34651ea72ea1c335d3170f234cb0517fd897f.tar.bz2 busybox-w32-3fd34651ea72ea1c335d3170f234cb0517fd897f.zip | |
Merge branch 'busybox' into merge
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/ash.c | 22 | ||||
| -rw-r--r-- | shell/hush.c | 40 | ||||
| -rw-r--r-- | shell/hush_test/hush-misc/while4.right | 1 | ||||
| -rwxr-xr-x | shell/hush_test/hush-misc/while4.tests | 6 | ||||
| -rw-r--r-- | shell/shell_common.c | 2 |
5 files changed, 57 insertions, 14 deletions
diff --git a/shell/ash.c b/shell/ash.c index 8f59dccda..6e6fc6a71 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
| @@ -9501,6 +9501,9 @@ static int getoptscmd(int, char **) FAST_FUNC; | |||
| 9501 | #if !ENABLE_FEATURE_SH_EXTRA_QUIET | 9501 | #if !ENABLE_FEATURE_SH_EXTRA_QUIET |
| 9502 | static int helpcmd(int, char **) FAST_FUNC; | 9502 | static int helpcmd(int, char **) FAST_FUNC; |
| 9503 | #endif | 9503 | #endif |
| 9504 | #if MAX_HISTORY | ||
| 9505 | static int historycmd(int, char **) FAST_FUNC; | ||
| 9506 | #endif | ||
| 9504 | #if ENABLE_SH_MATH_SUPPORT | 9507 | #if ENABLE_SH_MATH_SUPPORT |
| 9505 | static int letcmd(int, char **) FAST_FUNC; | 9508 | static int letcmd(int, char **) FAST_FUNC; |
| 9506 | #endif | 9509 | #endif |
| @@ -9574,6 +9577,9 @@ static const struct builtincmd builtintab[] = { | |||
| 9574 | #if !ENABLE_FEATURE_SH_EXTRA_QUIET | 9577 | #if !ENABLE_FEATURE_SH_EXTRA_QUIET |
| 9575 | { BUILTIN_NOSPEC "help" , helpcmd }, | 9578 | { BUILTIN_NOSPEC "help" , helpcmd }, |
| 9576 | #endif | 9579 | #endif |
| 9580 | #if MAX_HISTORY | ||
| 9581 | { BUILTIN_NOSPEC "history" , historycmd }, | ||
| 9582 | #endif | ||
| 9577 | #if JOBS | 9583 | #if JOBS |
| 9578 | { BUILTIN_REGULAR "jobs" , jobscmd }, | 9584 | { BUILTIN_REGULAR "jobs" , jobscmd }, |
| 9579 | { BUILTIN_REGULAR "kill" , killcmd }, | 9585 | { BUILTIN_REGULAR "kill" , killcmd }, |
| @@ -10155,7 +10161,12 @@ preadfd(void) | |||
| 10155 | * _during_ shell execution, not only if it was set when | 10161 | * _during_ shell execution, not only if it was set when |
| 10156 | * shell was started. Therefore, re-check LANG every time: | 10162 | * shell was started. Therefore, re-check LANG every time: |
| 10157 | */ | 10163 | */ |
| 10158 | reinit_unicode(lookupvar("LANG")); | 10164 | { |
| 10165 | const char *s = lookupvar("LC_ALL"); | ||
| 10166 | if (!s) s = lookupvar("LC_CTYPE"); | ||
| 10167 | if (!s) s = lookupvar("LANG"); | ||
| 10168 | reinit_unicode(s); | ||
| 10169 | } | ||
| 10159 | nr = read_line_input(line_input_state, cmdedit_prompt, buf, IBUFSIZ, timeout); | 10170 | nr = read_line_input(line_input_state, cmdedit_prompt, buf, IBUFSIZ, timeout); |
| 10160 | if (nr == 0) { | 10171 | if (nr == 0) { |
| 10161 | /* Ctrl+C pressed */ | 10172 | /* Ctrl+C pressed */ |
| @@ -13163,6 +13174,15 @@ helpcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
| 13163 | } | 13174 | } |
| 13164 | #endif /* FEATURE_SH_EXTRA_QUIET */ | 13175 | #endif /* FEATURE_SH_EXTRA_QUIET */ |
| 13165 | 13176 | ||
| 13177 | #if MAX_HISTORY | ||
| 13178 | static int FAST_FUNC | ||
| 13179 | historycmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | ||
| 13180 | { | ||
| 13181 | show_history(line_input_state); | ||
| 13182 | return EXIT_SUCCESS; | ||
| 13183 | } | ||
| 13184 | #endif | ||
| 13185 | |||
| 13166 | /* | 13186 | /* |
| 13167 | * The export and readonly commands. | 13187 | * The export and readonly commands. |
| 13168 | */ | 13188 | */ |
diff --git a/shell/hush.c b/shell/hush.c index b23325725..912ecf15f 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
| @@ -850,6 +850,9 @@ static int builtin_jobs(char **argv) FAST_FUNC; | |||
| 850 | #if ENABLE_HUSH_HELP | 850 | #if ENABLE_HUSH_HELP |
| 851 | static int builtin_help(char **argv) FAST_FUNC; | 851 | static int builtin_help(char **argv) FAST_FUNC; |
| 852 | #endif | 852 | #endif |
| 853 | #if MAX_HISTORY && ENABLE_FEATURE_EDITING | ||
| 854 | static int builtin_history(char **argv) FAST_FUNC; | ||
| 855 | #endif | ||
| 853 | #if ENABLE_HUSH_LOCAL | 856 | #if ENABLE_HUSH_LOCAL |
| 854 | static int builtin_local(char **argv) FAST_FUNC; | 857 | static int builtin_local(char **argv) FAST_FUNC; |
| 855 | #endif | 858 | #endif |
| @@ -919,6 +922,9 @@ static const struct built_in_command bltins1[] = { | |||
| 919 | #if ENABLE_HUSH_HELP | 922 | #if ENABLE_HUSH_HELP |
| 920 | BLTIN("help" , builtin_help , NULL), | 923 | BLTIN("help" , builtin_help , NULL), |
| 921 | #endif | 924 | #endif |
| 925 | #if MAX_HISTORY && ENABLE_FEATURE_EDITING | ||
| 926 | BLTIN("history" , builtin_history , "Show command history"), | ||
| 927 | #endif | ||
| 922 | #if ENABLE_HUSH_JOB | 928 | #if ENABLE_HUSH_JOB |
| 923 | BLTIN("jobs" , builtin_jobs , "List jobs"), | 929 | BLTIN("jobs" , builtin_jobs , "List jobs"), |
| 924 | #endif | 930 | #endif |
| @@ -1383,7 +1389,7 @@ static void restore_G_args(save_arg_t *sv, char **argv) | |||
| 1383 | * are set to '' (ignore) are NOT reset to defaults. We do the same. | 1389 | * are set to '' (ignore) are NOT reset to defaults. We do the same. |
| 1384 | * | 1390 | * |
| 1385 | * Problem: the above approach makes it unwieldy to catch signals while | 1391 | * Problem: the above approach makes it unwieldy to catch signals while |
| 1386 | * we are in read builtin, of while we read commands from stdin: | 1392 | * we are in read builtin, or while we read commands from stdin: |
| 1387 | * masked signals are not visible! | 1393 | * masked signals are not visible! |
| 1388 | * | 1394 | * |
| 1389 | * New implementation | 1395 | * New implementation |
| @@ -2038,7 +2044,10 @@ static void get_user_input(struct in_str *i) | |||
| 2038 | * _during_ shell execution, not only if it was set when | 2044 | * _during_ shell execution, not only if it was set when |
| 2039 | * shell was started. Therefore, re-check LANG every time: | 2045 | * shell was started. Therefore, re-check LANG every time: |
| 2040 | */ | 2046 | */ |
| 2041 | reinit_unicode(get_local_var_value("LANG")); | 2047 | const char *s = get_local_var_value("LC_ALL"); |
| 2048 | if (!s) s = get_local_var_value("LC_CTYPE"); | ||
| 2049 | if (!s) s = get_local_var_value("LANG"); | ||
| 2050 | reinit_unicode(s); | ||
| 2042 | 2051 | ||
| 2043 | G.flag_SIGINT = 0; | 2052 | G.flag_SIGINT = 0; |
| 2044 | /* buglet: SIGINT will not make new prompt to appear _at once_, | 2053 | /* buglet: SIGINT will not make new prompt to appear _at once_, |
| @@ -7354,7 +7363,7 @@ static int run_list(struct pipe *pi) | |||
| 7354 | * and we should not execute CMD */ | 7363 | * and we should not execute CMD */ |
| 7355 | debug_printf_exec("skipped cmd because of || or &&\n"); | 7364 | debug_printf_exec("skipped cmd because of || or &&\n"); |
| 7356 | last_followup = pi->followup; | 7365 | last_followup = pi->followup; |
| 7357 | continue; | 7366 | goto dont_check_jobs_but_continue; |
| 7358 | } | 7367 | } |
| 7359 | } | 7368 | } |
| 7360 | last_followup = pi->followup; | 7369 | last_followup = pi->followup; |
| @@ -7493,8 +7502,10 @@ static int run_list(struct pipe *pi) | |||
| 7493 | G.flag_break_continue = 0; | 7502 | G.flag_break_continue = 0; |
| 7494 | /* else: e.g. "continue 2" should *break* once, *then* continue */ | 7503 | /* else: e.g. "continue 2" should *break* once, *then* continue */ |
| 7495 | } /* else: "while... do... { we are here (innermost list is not a loop!) };...done" */ | 7504 | } /* else: "while... do... { we are here (innermost list is not a loop!) };...done" */ |
| 7496 | if (G.depth_break_continue != 0 || fbc == BC_BREAK) | 7505 | if (G.depth_break_continue != 0 || fbc == BC_BREAK) { |
| 7497 | goto check_jobs_and_break; | 7506 | checkjobs(NULL); |
| 7507 | break; | ||
| 7508 | } | ||
| 7498 | /* "continue": simulate end of loop */ | 7509 | /* "continue": simulate end of loop */ |
| 7499 | rword = RES_DONE; | 7510 | rword = RES_DONE; |
| 7500 | continue; | 7511 | continue; |
| @@ -7502,7 +7513,6 @@ static int run_list(struct pipe *pi) | |||
| 7502 | #endif | 7513 | #endif |
| 7503 | #if ENABLE_HUSH_FUNCTIONS | 7514 | #if ENABLE_HUSH_FUNCTIONS |
| 7504 | if (G.flag_return_in_progress == 1) { | 7515 | if (G.flag_return_in_progress == 1) { |
| 7505 | /* same as "goto check_jobs_and_break" */ | ||
| 7506 | checkjobs(NULL); | 7516 | checkjobs(NULL); |
| 7507 | break; | 7517 | break; |
| 7508 | } | 7518 | } |
| @@ -7544,6 +7554,9 @@ static int run_list(struct pipe *pi) | |||
| 7544 | if (rword == RES_IF || rword == RES_ELIF) | 7554 | if (rword == RES_IF || rword == RES_ELIF) |
| 7545 | cond_code = rcode; | 7555 | cond_code = rcode; |
| 7546 | #endif | 7556 | #endif |
| 7557 | check_jobs_and_continue: | ||
| 7558 | checkjobs(NULL); | ||
| 7559 | dont_check_jobs_but_continue: ; | ||
| 7547 | #if ENABLE_HUSH_LOOPS | 7560 | #if ENABLE_HUSH_LOOPS |
| 7548 | /* Beware of "while false; true; do ..."! */ | 7561 | /* Beware of "while false; true; do ..."! */ |
| 7549 | if (pi->next | 7562 | if (pi->next |
| @@ -7555,22 +7568,17 @@ static int run_list(struct pipe *pi) | |||
| 7555 | /* "while false; do...done" - exitcode 0 */ | 7568 | /* "while false; do...done" - exitcode 0 */ |
| 7556 | G.last_exitcode = rcode = EXIT_SUCCESS; | 7569 | G.last_exitcode = rcode = EXIT_SUCCESS; |
| 7557 | debug_printf_exec(": while expr is false: breaking (exitcode:EXIT_SUCCESS)\n"); | 7570 | debug_printf_exec(": while expr is false: breaking (exitcode:EXIT_SUCCESS)\n"); |
| 7558 | goto check_jobs_and_break; | 7571 | break; |
| 7559 | } | 7572 | } |
| 7560 | } | 7573 | } |
| 7561 | if (rword == RES_UNTIL) { | 7574 | if (rword == RES_UNTIL) { |
| 7562 | if (!rcode) { | 7575 | if (!rcode) { |
| 7563 | debug_printf_exec(": until expr is true: breaking\n"); | 7576 | debug_printf_exec(": until expr is true: breaking\n"); |
| 7564 | check_jobs_and_break: | ||
| 7565 | checkjobs(NULL); | ||
| 7566 | break; | 7577 | break; |
| 7567 | } | 7578 | } |
| 7568 | } | 7579 | } |
| 7569 | } | 7580 | } |
| 7570 | #endif | 7581 | #endif |
| 7571 | |||
| 7572 | check_jobs_and_continue: | ||
| 7573 | checkjobs(NULL); | ||
| 7574 | } /* for (pi) */ | 7582 | } /* for (pi) */ |
| 7575 | 7583 | ||
| 7576 | #if ENABLE_HUSH_JOB | 7584 | #if ENABLE_HUSH_JOB |
| @@ -8628,6 +8636,14 @@ static int FAST_FUNC builtin_help(char **argv UNUSED_PARAM) | |||
| 8628 | } | 8636 | } |
| 8629 | #endif | 8637 | #endif |
| 8630 | 8638 | ||
| 8639 | #if MAX_HISTORY && ENABLE_FEATURE_EDITING | ||
| 8640 | static int FAST_FUNC builtin_history(char **argv UNUSED_PARAM) | ||
| 8641 | { | ||
| 8642 | show_history(G.line_input_state); | ||
| 8643 | return EXIT_SUCCESS; | ||
| 8644 | } | ||
| 8645 | #endif | ||
| 8646 | |||
| 8631 | #if ENABLE_HUSH_JOB | 8647 | #if ENABLE_HUSH_JOB |
| 8632 | static int FAST_FUNC builtin_jobs(char **argv UNUSED_PARAM) | 8648 | static int FAST_FUNC builtin_jobs(char **argv UNUSED_PARAM) |
| 8633 | { | 8649 | { |
diff --git a/shell/hush_test/hush-misc/while4.right b/shell/hush_test/hush-misc/while4.right new file mode 100644 index 000000000..7b24a35ff --- /dev/null +++ b/shell/hush_test/hush-misc/while4.right | |||
| @@ -0,0 +1 @@ | |||
| Ok:0 | |||
diff --git a/shell/hush_test/hush-misc/while4.tests b/shell/hush_test/hush-misc/while4.tests new file mode 100755 index 000000000..ba80e603a --- /dev/null +++ b/shell/hush_test/hush-misc/while4.tests | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | false | ||
| 2 | while false && echo Not reached; do | ||
| 3 | echo BUG | ||
| 4 | break | ||
| 5 | done | ||
| 6 | echo Ok:$? | ||
diff --git a/shell/shell_common.c b/shell/shell_common.c index f7503cac5..84e0604ed 100644 --- a/shell/shell_common.c +++ b/shell/shell_common.c | |||
| @@ -39,7 +39,7 @@ int FAST_FUNC is_well_formed_var_name(const char *s, char terminator) | |||
| 39 | 39 | ||
| 40 | /* read builtin */ | 40 | /* read builtin */ |
| 41 | 41 | ||
| 42 | /* Needs to be interruptible: shell mush handle traps and shell-special signals | 42 | /* Needs to be interruptible: shell must handle traps and shell-special signals |
| 43 | * while inside read. To implement this, be sure to not loop on EINTR | 43 | * while inside read. To implement this, be sure to not loop on EINTR |
| 44 | * and return errno == EINTR reliably. | 44 | * and return errno == EINTR reliably. |
| 45 | */ | 45 | */ |
