aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2022-02-09 09:03:18 +0000
committerRon Yorston <rmy@pobox.com>2022-02-09 09:05:39 +0000
commit492d0a7492a57fe8f02c766e25960b0ce0d88759 (patch)
tree4f5764a5c2250c031ea05e9aeacbb40d7971f493 /shell
parent4734416a21312488a5099a297907783bee4ccc22 (diff)
parentcaa9c4f707b661cf398f2c2d66f54f5b0d8adfe2 (diff)
downloadbusybox-w32-492d0a7492a57fe8f02c766e25960b0ce0d88759.tar.gz
busybox-w32-492d0a7492a57fe8f02c766e25960b0ce0d88759.tar.bz2
busybox-w32-492d0a7492a57fe8f02c766e25960b0ce0d88759.zip
Merge busybox into merge
Fix conflicts in reset and ash. Redefine the new safe_read_key() as a reference to read_key(). Disable SHA256_HWACCEL.
Diffstat (limited to 'shell')
-rw-r--r--shell/ash.c48
-rw-r--r--shell/hush.c79
-rw-r--r--shell/shell_common.c1
3 files changed, 90 insertions, 38 deletions
diff --git a/shell/ash.c b/shell/ash.c
index a1d01447a..46c4f1675 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -428,7 +428,7 @@ static void forkshell_print(FILE *fp0, struct forkshell *fs, const char **notes)
428/* ============ Shell options */ 428/* ============ Shell options */
429 429
430/* If you add/change options hare, update --help text too */ 430/* If you add/change options hare, update --help text too */
431static const char *const optletters_optnames[] = { 431static const char *const optletters_optnames[] ALIGN_PTR = {
432 "e" "errexit", 432 "e" "errexit",
433 "f" "noglob", 433 "f" "noglob",
434/* bash has '-o ignoreeof', but no short synonym -I for it */ 434/* bash has '-o ignoreeof', but no short synonym -I for it */
@@ -845,7 +845,7 @@ raise_exception(int e)
845/* 845/*
846 * Called when a SIGINT is received. (If the user specifies 846 * Called when a SIGINT is received. (If the user specifies
847 * that SIGINT is to be trapped or ignored using the trap builtin, then 847 * that SIGINT is to be trapped or ignored using the trap builtin, then
848 * this routine is not called.) Suppressint is nonzero when interrupts 848 * this routine is not called.) suppress_int is nonzero when interrupts
849 * are held using the INT_OFF macro. (The test for iflag is just 849 * are held using the INT_OFF macro. (The test for iflag is just
850 * defensive programming.) 850 * defensive programming.)
851 */ 851 */
@@ -882,13 +882,12 @@ raise_interrupt(void)
882} while (0) 882} while (0)
883#endif 883#endif
884 884
885static IF_ASH_OPTIMIZE_FOR_SIZE(inline) void 885static IF_NOT_ASH_OPTIMIZE_FOR_SIZE(inline) void
886int_on(void) 886int_on(void)
887{ 887{
888 barrier(); 888 barrier();
889 if (--suppress_int == 0 && pending_int) { 889 if (--suppress_int == 0 && pending_int)
890 raise_interrupt(); 890 raise_interrupt();
891 }
892} 891}
893#if DEBUG_INTONOFF 892#if DEBUG_INTONOFF
894# define INT_ON do { \ 893# define INT_ON do { \
@@ -898,7 +897,7 @@ int_on(void)
898#else 897#else
899# define INT_ON int_on() 898# define INT_ON int_on()
900#endif 899#endif
901static IF_ASH_OPTIMIZE_FOR_SIZE(inline) void 900static IF_NOT_ASH_OPTIMIZE_FOR_SIZE(inline) void
902force_int_on(void) 901force_int_on(void)
903{ 902{
904 barrier(); 903 barrier();
@@ -4143,7 +4142,9 @@ signal_handler(int signo)
4143 if (!trap[SIGCHLD]) 4142 if (!trap[SIGCHLD])
4144 return; 4143 return;
4145 } 4144 }
4146 4145#if ENABLE_FEATURE_EDITING
4146 bb_got_signal = signo; /* for read_line_input: "we got a signal" */
4147#endif
4147 gotsig[signo - 1] = 1; 4148 gotsig[signo - 1] = 1;
4148 pending_sig = signo; 4149 pending_sig = signo;
4149 4150
@@ -11656,33 +11657,56 @@ preadfd(void)
11656# endif 11657# endif
11657 reinit_unicode_for_ash(); 11658 reinit_unicode_for_ash();
11658 again: 11659 again:
11660 /* For shell, LI_INTERRUPTIBLE is set:
11661 * read_line_input will abort on either
11662 * getting EINTR in poll(), or if it sees bb_got_signal != 0
11663 * (IOW: if signal arrives before poll() is reached).
11664 * Interactive testcases:
11665 * (while kill -INT $$; do sleep 1; done) &
11666 * #^^^ prints ^C, prints prompt, repeats
11667 * trap 'echo I' int; (while kill -INT $$; do sleep 1; done) &
11668 * #^^^ prints ^C, prints "I", prints prompt, repeats
11669 * trap 'echo T' term; (while kill $$; do sleep 1; done) &
11670 * #^^^ prints "T", prints prompt, repeats
11671 * #(bash 5.0.17 exits after first "T", looks like a bug)
11672 */
11673 bb_got_signal = 0;
11674 INT_OFF; /* no longjmp'ing out of read_line_input please */
11659 nr = read_line_input(line_input_state, cmdedit_prompt, buf, IBUFSIZ); 11675 nr = read_line_input(line_input_state, cmdedit_prompt, buf, IBUFSIZ);
11676 if (bb_got_signal == SIGINT)
11677 write(STDOUT_FILENO, "^C\n", 3);
11678 INT_ON; /* here non-blocked SIGINT will longjmp */
11660 if (nr == 0) { 11679 if (nr == 0) {
11661 /* ^C pressed, "convert" to SIGINT */ 11680 /* ^C pressed, "convert" to SIGINT */
11662# if !ENABLE_PLATFORM_MINGW32 11681# if !ENABLE_PLATFORM_MINGW32
11663 write(STDOUT_FILENO, "^C", 2); 11682 write(STDOUT_FILENO, "^C\n", 3);
11664 raise(SIGINT); 11683 raise(SIGINT); /* here non-blocked SIGINT will longjmp */
11665 /* raise(SIGINT) did not work! (e.g. if SIGINT 11684 /* raise(SIGINT) did not work! (e.g. if SIGINT
11666 * is SIG_INGed on startup, it stays SIG_IGNed) 11685 * is SIG_IGNed on startup, it stays SIG_IGNed)
11667 */ 11686 */
11668# else 11687# else
11669 raise_interrupt(); 11688 raise_interrupt();
11670# endif 11689# endif
11671 if (trap[SIGINT]) { 11690 if (trap[SIGINT]) {
11691 empty_line_input:
11672 buf[0] = '\n'; 11692 buf[0] = '\n';
11673 buf[1] = '\0'; 11693 buf[1] = '\0';
11674 return 1; 11694 return 1;
11675 } 11695 }
11676 exitstatus = 128 + SIGINT; 11696 exitstatus = 128 + SIGINT;
11677 /* bash behavior on ^C + ignored SIGINT: */ 11697 /* bash behavior on ^C + ignored SIGINT: */
11678 write(STDOUT_FILENO, "\n", 1);
11679 goto again; 11698 goto again;
11680 } 11699 }
11681 if (nr < 0) { 11700 if (nr < 0) {
11682 if (errno == 0) { 11701 if (errno == 0) {
11683 /* Ctrl+D pressed */ 11702 /* ^D pressed */
11684 nr = 0; 11703 nr = 0;
11685 } 11704 }
11705 else if (errno == EINTR) { /* got signal? */
11706 if (bb_got_signal != SIGINT)
11707 write(STDOUT_FILENO, "\n", 1);
11708 goto empty_line_input;
11709 }
11686# if ENABLE_ASH_IDLE_TIMEOUT 11710# if ENABLE_ASH_IDLE_TIMEOUT
11687 else if (errno == EAGAIN && timeout > 0) { 11711 else if (errno == EAGAIN && timeout > 0) {
11688 puts("\007timed out waiting for input: auto-logout"); 11712 puts("\007timed out waiting for input: auto-logout");
diff --git a/shell/hush.c b/shell/hush.c
index 982fc356a..ae81f0da5 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -564,7 +564,7 @@ enum {
564#define NULL_O_STRING { NULL } 564#define NULL_O_STRING { NULL }
565 565
566#ifndef debug_printf_parse 566#ifndef debug_printf_parse
567static const char *const assignment_flag[] = { 567static const char *const assignment_flag[] ALIGN_PTR = {
568 "MAYBE_ASSIGNMENT", 568 "MAYBE_ASSIGNMENT",
569 "DEFINITELY_ASSIGNMENT", 569 "DEFINITELY_ASSIGNMENT",
570 "NOT_ASSIGNMENT", 570 "NOT_ASSIGNMENT",
@@ -918,6 +918,7 @@ struct globals {
918#if ENABLE_HUSH_INTERACTIVE 918#if ENABLE_HUSH_INTERACTIVE
919 smallint promptmode; /* 0: PS1, 1: PS2 */ 919 smallint promptmode; /* 0: PS1, 1: PS2 */
920#endif 920#endif
921 /* set by signal handler if SIGINT is received _and_ its trap is not set */
921 smallint flag_SIGINT; 922 smallint flag_SIGINT;
922#if ENABLE_HUSH_LOOPS 923#if ENABLE_HUSH_LOOPS
923 smallint flag_break_continue; 924 smallint flag_break_continue;
@@ -1944,6 +1945,9 @@ enum {
1944static void record_pending_signo(int sig) 1945static void record_pending_signo(int sig)
1945{ 1946{
1946 sigaddset(&G.pending_set, sig); 1947 sigaddset(&G.pending_set, sig);
1948#if ENABLE_FEATURE_EDITING
1949 bb_got_signal = sig; /* for read_line_input: "we got a signal" */
1950#endif
1947#if ENABLE_HUSH_FAST 1951#if ENABLE_HUSH_FAST
1948 if (sig == SIGCHLD) { 1952 if (sig == SIGCHLD) {
1949 G.count_SIGCHLD++; 1953 G.count_SIGCHLD++;
@@ -2652,30 +2656,53 @@ static int get_user_input(struct in_str *i)
2652 for (;;) { 2656 for (;;) {
2653 reinit_unicode_for_hush(); 2657 reinit_unicode_for_hush();
2654 G.flag_SIGINT = 0; 2658 G.flag_SIGINT = 0;
2655 /* buglet: SIGINT will not make new prompt to appear _at once_, 2659
2656 * only after <Enter>. (^C works immediately) */ 2660 bb_got_signal = 0;
2657 r = read_line_input(G.line_input_state, prompt_str, 2661 if (!sigisemptyset(&G.pending_set)) {
2662 /* Whoops, already got a signal, do not call read_line_input */
2663 bb_got_signal = r = -1;
2664 } else {
2665 /* For shell, LI_INTERRUPTIBLE is set:
2666 * read_line_input will abort on either
2667 * getting EINTR in poll(), or if it sees bb_got_signal != 0
2668 * (IOW: if signal arrives before poll() is reached).
2669 * Interactive testcases:
2670 * (while kill -INT $$; do sleep 1; done) &
2671 * #^^^ prints ^C, prints prompt, repeats
2672 * trap 'echo I' int; (while kill -INT $$; do sleep 1; done) &
2673 * #^^^ prints ^C, prints "I", prints prompt, repeats
2674 * trap 'echo T' term; (while kill $$; do sleep 1; done) &
2675 * #^^^ prints "T", prints prompt, repeats
2676 * #(bash 5.0.17 exits after first "T", looks like a bug)
2677 */
2678 r = read_line_input(G.line_input_state, prompt_str,
2658 G.user_input_buf, CONFIG_FEATURE_EDITING_MAX_LEN-1 2679 G.user_input_buf, CONFIG_FEATURE_EDITING_MAX_LEN-1
2659 ); 2680 );
2660 /* read_line_input intercepts ^C, "convert" it to SIGINT */ 2681 /* read_line_input intercepts ^C, "convert" it to SIGINT */
2661 if (r == 0) { 2682 if (r == 0)
2662 raise(SIGINT); 2683 raise(SIGINT);
2684 }
2685 /* bash prints ^C (before running a trap, if any)
2686 * both on keyboard ^C and on real SIGINT (non-kbd generated).
2687 */
2688 if (sigismember(&G.pending_set, SIGINT)) {
2689 write(STDOUT_FILENO, "^C\n", 3);
2690 G.last_exitcode = 128 | SIGINT;
2663 } 2691 }
2664 check_and_run_traps(); 2692 check_and_run_traps();
2665 if (r != 0 && !G.flag_SIGINT) 2693 if (r == 0) /* keyboard ^C? */
2694 continue; /* go back, read another input line */
2695 if (r > 0) /* normal input? (no ^C, no ^D, no signals) */
2666 break; 2696 break;
2667 /* ^C or SIGINT: repeat */ 2697 if (!bb_got_signal) {
2668 /* bash prints ^C even on real SIGINT (non-kbd generated) */ 2698 /* r < 0: ^D/EOF/error detected (but not signal) */
2669 write(STDOUT_FILENO, "^C\n", 3); 2699 /* ^D on interactive input goes to next line before exiting: */
2670 G.last_exitcode = 128 | SIGINT; 2700 write(STDOUT_FILENO, "\n", 1);
2671 } 2701 i->p = NULL;
2672 if (r < 0) { 2702 i->peek_buf[0] = r = EOF;
2673 /* EOF/error detected */ 2703 return r;
2674 /* ^D on interactive input goes to next line before exiting: */ 2704 }
2675 write(STDOUT_FILENO, "\n", 1); 2705 /* it was a signal: go back, read another input line */
2676 i->p = NULL;
2677 i->peek_buf[0] = r = EOF;
2678 return r;
2679 } 2706 }
2680 i->p = G.user_input_buf; 2707 i->p = G.user_input_buf;
2681 return (unsigned char)*i->p++; 2708 return (unsigned char)*i->p++;
@@ -3655,7 +3682,7 @@ static void free_pipe_list(struct pipe *pi)
3655#ifndef debug_print_tree 3682#ifndef debug_print_tree
3656static void debug_print_tree(struct pipe *pi, int lvl) 3683static void debug_print_tree(struct pipe *pi, int lvl)
3657{ 3684{
3658 static const char *const PIPE[] = { 3685 static const char *const PIPE[] ALIGN_PTR = {
3659 [PIPE_SEQ] = "SEQ", 3686 [PIPE_SEQ] = "SEQ",
3660 [PIPE_AND] = "AND", 3687 [PIPE_AND] = "AND",
3661 [PIPE_OR ] = "OR" , 3688 [PIPE_OR ] = "OR" ,
@@ -3690,7 +3717,7 @@ static void debug_print_tree(struct pipe *pi, int lvl)
3690 [RES_XXXX ] = "XXXX" , 3717 [RES_XXXX ] = "XXXX" ,
3691 [RES_SNTX ] = "SNTX" , 3718 [RES_SNTX ] = "SNTX" ,
3692 }; 3719 };
3693 static const char *const CMDTYPE[] = { 3720 static const char *const CMDTYPE[] ALIGN_PTR = {
3694 "{}", 3721 "{}",
3695 "()", 3722 "()",
3696 "[noglob]", 3723 "[noglob]",
@@ -7632,7 +7659,7 @@ static int generate_stream_from_string(const char *s, pid_t *pid_p)
7632 if (is_prefixed_with(s, "trap") 7659 if (is_prefixed_with(s, "trap")
7633 && skip_whitespace(s + 4)[0] == '\0' 7660 && skip_whitespace(s + 4)[0] == '\0'
7634 ) { 7661 ) {
7635 static const char *const argv[] = { NULL, NULL }; 7662 static const char *const argv[] ALIGN_PTR = { NULL, NULL };
7636 builtin_trap((char**)argv); 7663 builtin_trap((char**)argv);
7637 fflush_all(); /* important */ 7664 fflush_all(); /* important */
7638 _exit(0); 7665 _exit(0);
@@ -9799,7 +9826,7 @@ static int run_list(struct pipe *pi)
9799 static const char encoded_dollar_at[] ALIGN1 = { 9826 static const char encoded_dollar_at[] ALIGN1 = {
9800 SPECIAL_VAR_SYMBOL, '@' | 0x80, SPECIAL_VAR_SYMBOL, '\0' 9827 SPECIAL_VAR_SYMBOL, '@' | 0x80, SPECIAL_VAR_SYMBOL, '\0'
9801 }; /* encoded representation of "$@" */ 9828 }; /* encoded representation of "$@" */
9802 static const char *const encoded_dollar_at_argv[] = { 9829 static const char *const encoded_dollar_at_argv[] ALIGN_PTR = {
9803 encoded_dollar_at, NULL 9830 encoded_dollar_at, NULL
9804 }; /* argv list with one element: "$@" */ 9831 }; /* argv list with one element: "$@" */
9805 char **vals; 9832 char **vals;
@@ -10361,7 +10388,7 @@ int hush_main(int argc, char **argv)
10361//it ignores TERM: 10388//it ignores TERM:
10362// bash -i -c 'kill $$; echo ALIVE' 10389// bash -i -c 'kill $$; echo ALIVE'
10363// ALIVE 10390// ALIVE
10364//it resets SIG_INGed HUP to SIG_DFL: 10391//it resets SIG_IGNed HUP to SIG_DFL:
10365// trap '' hup; bash -i -c 'kill -hup $$; echo ALIVE' 10392// trap '' hup; bash -i -c 'kill -hup $$; echo ALIVE'
10366// Hangup [the message is not printed by bash, it's the shell which started it] 10393// Hangup [the message is not printed by bash, it's the shell which started it]
10367//is talkative about jobs and exiting: 10394//is talkative about jobs and exiting:
diff --git a/shell/shell_common.c b/shell/shell_common.c
index fff356c04..399d5e684 100644
--- a/shell/shell_common.c
+++ b/shell/shell_common.c
@@ -218,6 +218,7 @@ shell_builtin_read(struct builtin_read_params *params)
218 */ 218 */
219 errno = 0; 219 errno = 0;
220 pfd[0].events = POLLIN; 220 pfd[0].events = POLLIN;
221//TODO race with a signal arriving just before the poll!
221 if (poll(pfd, 1, timeout) <= 0) { 222 if (poll(pfd, 1, timeout) <= 0) {
222 /* timed out, or EINTR */ 223 /* timed out, or EINTR */
223 err = errno; 224 err = errno;