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 | */ |