diff options
| author | Ron Yorston <rmy@pobox.com> | 2025-08-10 07:46:58 +0100 |
|---|---|---|
| committer | Ron Yorston <rmy@pobox.com> | 2025-08-10 07:46:58 +0100 |
| commit | c70a65f36c017f6feb7e86415bec1a644e71dbab (patch) | |
| tree | e1c3afca24fd35bd2ff142cc0ea83151fdfa5996 /shell | |
| parent | dcb4966c5492aeb67494d9ffdc58ff3054add443 (diff) | |
| parent | 84766710f420dd444e2a03d33a1915ce55661e67 (diff) | |
| download | busybox-w32-c70a65f36c017f6feb7e86415bec1a644e71dbab.tar.gz busybox-w32-c70a65f36c017f6feb7e86415bec1a644e71dbab.tar.bz2 busybox-w32-c70a65f36c017f6feb7e86415bec1a644e71dbab.zip | |
Merge branch 'busybox' into merge
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/Config.src | 7 | ||||
| -rw-r--r-- | shell/ash.c | 33 | ||||
| -rw-r--r-- | shell/ash_test/ash-read/read_ifs2.right | 9 | ||||
| -rwxr-xr-x | shell/ash_test/ash-read/read_ifs2.tests | 9 | ||||
| -rw-r--r-- | shell/ash_test/ash-read/read_t.right | 8 | ||||
| -rwxr-xr-x | shell/ash_test/ash-read/read_t.tests | 18 | ||||
| -rw-r--r-- | shell/ash_test/printenv.c | 4 | ||||
| -rw-r--r-- | shell/ash_test/recho.c | 2 | ||||
| -rw-r--r-- | shell/hush.c | 48 | ||||
| -rw-r--r-- | shell/hush_test/hush-read/read_t.right | 8 | ||||
| -rwxr-xr-x | shell/hush_test/hush-read/read_t.tests | 18 | ||||
| -rw-r--r-- | shell/shell_common.c | 22 |
12 files changed, 129 insertions, 57 deletions
diff --git a/shell/Config.src b/shell/Config.src index 5efbf9995..5b3fe08f3 100644 --- a/shell/Config.src +++ b/shell/Config.src | |||
| @@ -166,9 +166,10 @@ config FEATURE_SH_HISTFILESIZE | |||
| 166 | default y | 166 | default y |
| 167 | depends on SHELL_ASH || SHELL_HUSH | 167 | depends on SHELL_ASH || SHELL_HUSH |
| 168 | help | 168 | help |
| 169 | This option makes busybox shells to use $HISTFILESIZE variable | 169 | This option makes busybox shells to use $HISTSIZE and |
| 170 | to set shell history size. Note that its max value is capped | 170 | $HISTFILESIZE variables to set shell history size. |
| 171 | by "History size" setting in library tuning section. | 171 | Note that its max value is capped by "History size" setting |
| 172 | in library tuning section. | ||
| 172 | 173 | ||
| 173 | config FEATURE_SH_EMBEDDED_SCRIPTS | 174 | config FEATURE_SH_EMBEDDED_SCRIPTS |
| 174 | bool "Embed scripts in the binary" | 175 | bool "Embed scripts in the binary" |
diff --git a/shell/ash.c b/shell/ash.c index 99fbf6053..0038aa1e9 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
| @@ -4275,7 +4275,7 @@ signal_handler(int signo) | |||
| 4275 | return; | 4275 | return; |
| 4276 | } | 4276 | } |
| 4277 | #if ENABLE_FEATURE_EDITING | 4277 | #if ENABLE_FEATURE_EDITING |
| 4278 | bb_got_signal = signo; /* for read_line_input: "we got a signal" */ | 4278 | bb_got_signal = signo; /* for read_line_input / read builtin: "we got a signal" */ |
| 4279 | #endif | 4279 | #endif |
| 4280 | gotsig[signo - 1] = 1; | 4280 | gotsig[signo - 1] = 1; |
| 4281 | pending_sig = signo; | 4281 | pending_sig = signo; |
| @@ -15821,6 +15821,11 @@ readcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) | |||
| 15821 | if (pending_sig == 0) | 15821 | if (pending_sig == 0) |
| 15822 | goto again; | 15822 | goto again; |
| 15823 | } | 15823 | } |
| 15824 | |||
| 15825 | if ((uintptr_t)r == 2) /* -t SEC timeout? */ | ||
| 15826 | /* bash: "The exit status is greater than 128 if the timeout is exceeded." */ | ||
| 15827 | /* The actual value observed with bash 5.2.15: */ | ||
| 15828 | return 128 + SIGALRM; | ||
| 15824 | #else /* ENABLE_PLATFORM_MINGW32 */ | 15829 | #else /* ENABLE_PLATFORM_MINGW32 */ |
| 15825 | if ((uintptr_t)r == 2) { | 15830 | if ((uintptr_t)r == 2) { |
| 15826 | /* Timeout, return 128 + SIGALRM */ | 15831 | /* Timeout, return 128 + SIGALRM */ |
| @@ -15973,8 +15978,25 @@ exitshell(void) | |||
| 15973 | char *p; | 15978 | char *p; |
| 15974 | 15979 | ||
| 15975 | #if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT | 15980 | #if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT |
| 15976 | save_history(line_input_state); /* may be NULL */ | 15981 | if (line_input_state) { |
| 15982 | const char *hp; | ||
| 15983 | # if ENABLE_FEATURE_SH_HISTFILESIZE | ||
| 15984 | // in bash: | ||
| 15985 | // HISTFILESIZE controls the on-disk history file size (in lines, 0=no history): | ||
| 15986 | // "When this variable is assigned a value, the history file is truncated, if necessary" | ||
| 15987 | // but we do it only at exit, not on assignment: | ||
| 15988 | /* Use HISTFILESIZE to limit file size */ | ||
| 15989 | hp = lookupvar("HISTFILESIZE"); | ||
| 15990 | if (hp) | ||
| 15991 | line_input_state->max_history = size_from_HISTFILESIZE(hp); | ||
| 15992 | # endif | ||
| 15993 | /* HISTFILE: "If unset, the command history is not saved when a shell exits." */ | ||
| 15994 | hp = lookupvar("HISTFILE"); | ||
| 15995 | line_input_state->hist_file = hp; | ||
| 15996 | save_history(line_input_state); /* no-op if hist_file is NULL or "" */ | ||
| 15997 | } | ||
| 15977 | #endif | 15998 | #endif |
| 15999 | |||
| 15978 | savestatus = exitstatus; | 16000 | savestatus = exitstatus; |
| 15979 | TRACE(("pid %d, exitshell(%d)\n", getpid(), savestatus)); | 16001 | TRACE(("pid %d, exitshell(%d)\n", getpid(), savestatus)); |
| 15980 | if (setjmp(loc.loc)) | 16002 | if (setjmp(loc.loc)) |
| @@ -16478,7 +16500,12 @@ int ash_main(int argc UNUSED_PARAM, char **argv) | |||
| 16478 | if (hp) | 16500 | if (hp) |
| 16479 | line_input_state->hist_file = xstrdup(hp); | 16501 | line_input_state->hist_file = xstrdup(hp); |
| 16480 | # if ENABLE_FEATURE_SH_HISTFILESIZE | 16502 | # if ENABLE_FEATURE_SH_HISTFILESIZE |
| 16481 | hp = lookupvar("HISTFILESIZE"); | 16503 | hp = lookupvar("HISTSIZE"); |
| 16504 | /* Using HISTFILESIZE above to limit max_history would be WRONG: | ||
| 16505 | * users may set HISTFILESIZE=0 in their profile scripts | ||
| 16506 | * to prevent _saving_ of history files, but still want to have | ||
| 16507 | * non-zero history limit for in-memory list. | ||
| 16508 | */ | ||
| 16482 | line_input_state->max_history = size_from_HISTFILESIZE(hp); | 16509 | line_input_state->max_history = size_from_HISTFILESIZE(hp); |
| 16483 | # endif | 16510 | # endif |
| 16484 | } | 16511 | } |
diff --git a/shell/ash_test/ash-read/read_ifs2.right b/shell/ash_test/ash-read/read_ifs2.right new file mode 100644 index 000000000..797137dae --- /dev/null +++ b/shell/ash_test/ash-read/read_ifs2.right | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | |X|Y:Z:| | ||
| 2 | |X|Y:Z| | ||
| 3 | |X|Y| | ||
| 4 | |X|Y| | ||
| 5 | |X|| | ||
| 6 | |X|| | ||
| 7 | ||| | ||
| 8 | Whitespace should be trimmed too: | ||
| 9 | |X|Y| | ||
diff --git a/shell/ash_test/ash-read/read_ifs2.tests b/shell/ash_test/ash-read/read_ifs2.tests new file mode 100755 index 000000000..f01a68978 --- /dev/null +++ b/shell/ash_test/ash-read/read_ifs2.tests | |||
| @@ -0,0 +1,9 @@ | |||
| 1 | echo "X:Y:Z:" | (IFS=": " read x y; echo "|$x|$y|") | ||
| 2 | echo "X:Y:Z" | (IFS=": " read x y; echo "|$x|$y|") | ||
| 3 | echo "X:Y:" | (IFS=": " read x y; echo "|$x|$y|") | ||
| 4 | echo "X:Y" | (IFS=": " read x y; echo "|$x|$y|") | ||
| 5 | echo "X:" | (IFS=": " read x y; echo "|$x|$y|") | ||
| 6 | echo "X" | (IFS=": " read x y; echo "|$x|$y|") | ||
| 7 | echo "" | (IFS=": " read x y; echo "|$x|$y|") | ||
| 8 | echo Whitespace should be trimmed too: | ||
| 9 | echo "X:Y : " | (IFS=": " read x y; echo "|$x|$y|") | ||
diff --git a/shell/ash_test/ash-read/read_t.right b/shell/ash_test/ash-read/read_t.right index 04126cbe6..3eedae275 100644 --- a/shell/ash_test/ash-read/read_t.right +++ b/shell/ash_test/ash-read/read_t.right | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | >< | 1 | >te:142< |
| 2 | >< | 2 | >:142< |
| 3 | >test< | 3 | >test:0< |
| 4 | >test< | 4 | >test:0< |
diff --git a/shell/ash_test/ash-read/read_t.tests b/shell/ash_test/ash-read/read_t.tests index d65f1aeaa..9fbeec517 100755 --- a/shell/ash_test/ash-read/read_t.tests +++ b/shell/ash_test/ash-read/read_t.tests | |||
| @@ -1,10 +1,10 @@ | |||
| 1 | # bash 3.2 outputs: | 1 | # bash 5.2 outputs: |
| 2 | 2 | ||
| 3 | # >< | 3 | # >te:142< |
| 4 | { echo -n 'te'; sleep 2; echo 'st'; } | (read -t 1 reply; echo ">$reply<") | 4 | { echo -n 'te'; sleep 2; echo 'st'; } | (read -t 1 reply; echo ">$reply:$?<") |
| 5 | # >< | 5 | # >:142< |
| 6 | { sleep 2; echo 'test'; } | (read -t 1 reply; echo ">$reply<") | 6 | { sleep 2; echo 'test'; } | (read -t 1 reply; echo ">$reply:$?<") |
| 7 | # >test< | 7 | # >test:0< |
| 8 | { echo -n 'te'; sleep 1; echo 'st'; } | (read -t 2 reply; echo ">$reply<") | 8 | { echo -n 'te'; sleep 1; echo 'st'; } | (read -t 2 reply; echo ">$reply:$?<") |
| 9 | # >test< | 9 | # >test:0< |
| 10 | { sleep 1; echo 'test'; } | (read -t 2 reply; echo ">$reply<") | 10 | { sleep 1; echo 'test'; } | (read -t 2 reply; echo ">$reply:$?<") |
diff --git a/shell/ash_test/printenv.c b/shell/ash_test/printenv.c index c86308d3b..f0f41984d 100644 --- a/shell/ash_test/printenv.c +++ b/shell/ash_test/printenv.c | |||
| @@ -31,9 +31,7 @@ | |||
| 31 | extern char **environ; | 31 | extern char **environ; |
| 32 | 32 | ||
| 33 | int | 33 | int |
| 34 | main (argc, argv) | 34 | main (int argc, char **argv) |
| 35 | int argc; | ||
| 36 | char **argv; | ||
| 37 | { | 35 | { |
| 38 | register char **envp, *eval; | 36 | register char **envp, *eval; |
| 39 | int len; | 37 | int len; |
diff --git a/shell/ash_test/recho.c b/shell/ash_test/recho.c index 42a5feafd..7e96b14cc 100644 --- a/shell/ash_test/recho.c +++ b/shell/ash_test/recho.c | |||
| @@ -27,7 +27,7 @@ | |||
| 27 | #include <stdio.h> | 27 | #include <stdio.h> |
| 28 | #include <stdlib.h> | 28 | #include <stdlib.h> |
| 29 | 29 | ||
| 30 | void strprint(); | 30 | void strprint(char *); |
| 31 | 31 | ||
| 32 | int main(int argc, char **argv) | 32 | int main(int argc, char **argv) |
| 33 | { | 33 | { |
diff --git a/shell/hush.c b/shell/hush.c index 4a97293cc..0b2bc01f5 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
| @@ -1973,7 +1973,7 @@ static void record_pending_signo(int sig) | |||
| 1973 | || (G_traps && G_traps[SIGCHLD] && G_traps[SIGCHLD][0]) | 1973 | || (G_traps && G_traps[SIGCHLD] && G_traps[SIGCHLD][0]) |
| 1974 | /* ^^^ if SIGCHLD, interrupt line reading only if it has a trap */ | 1974 | /* ^^^ if SIGCHLD, interrupt line reading only if it has a trap */ |
| 1975 | ) { | 1975 | ) { |
| 1976 | bb_got_signal = sig; /* for read_line_input: "we got a signal" */ | 1976 | bb_got_signal = sig; /* for read_line_input / read builtin: "we got a signal" */ |
| 1977 | } | 1977 | } |
| 1978 | #endif | 1978 | #endif |
| 1979 | #if ENABLE_HUSH_FAST | 1979 | #if ENABLE_HUSH_FAST |
| @@ -2099,11 +2099,29 @@ static sighandler_t pick_sighandler(unsigned sig) | |||
| 2099 | return handler; | 2099 | return handler; |
| 2100 | } | 2100 | } |
| 2101 | 2101 | ||
| 2102 | static const char* FAST_FUNC get_local_var_value(const char *name); | ||
| 2103 | |||
| 2102 | /* Restores tty foreground process group, and exits. */ | 2104 | /* Restores tty foreground process group, and exits. */ |
| 2103 | static void hush_exit(int exitcode) | 2105 | static void hush_exit(int exitcode) |
| 2104 | { | 2106 | { |
| 2105 | #if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT | 2107 | #if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT |
| 2106 | save_history(G.line_input_state); /* may be NULL */ | 2108 | if (G.line_input_state) { |
| 2109 | const char *hp; | ||
| 2110 | # if ENABLE_FEATURE_SH_HISTFILESIZE | ||
| 2111 | // in bash: | ||
| 2112 | // HISTFILESIZE controls the on-disk history file size (in lines, 0=no history): | ||
| 2113 | // "When this variable is assigned a value, the history file is truncated, if necessary" | ||
| 2114 | // but we do it only at exit, not on every assignment: | ||
| 2115 | /* Use HISTFILESIZE to limit file size */ | ||
| 2116 | hp = get_local_var_value("HISTFILESIZE"); | ||
| 2117 | if (hp) | ||
| 2118 | G.line_input_state->max_history = size_from_HISTFILESIZE(hp); | ||
| 2119 | # endif | ||
| 2120 | /* HISTFILE: "If unset, the command history is not saved when a shell exits." */ | ||
| 2121 | hp = get_local_var_value("HISTFILE"); | ||
| 2122 | G.line_input_state->hist_file = hp; | ||
| 2123 | save_history(G.line_input_state); /* no-op if hist_file is NULL or "" */ | ||
| 2124 | } | ||
| 2107 | #endif | 2125 | #endif |
| 2108 | 2126 | ||
| 2109 | fflush_all(); | 2127 | fflush_all(); |
| @@ -10427,7 +10445,7 @@ int hush_main(int argc, char **argv) | |||
| 10427 | if (!get_local_var_value("PATH")) | 10445 | if (!get_local_var_value("PATH")) |
| 10428 | set_local_var_from_halves("PATH", bb_default_root_path); | 10446 | set_local_var_from_halves("PATH", bb_default_root_path); |
| 10429 | 10447 | ||
| 10430 | /* PS1/PS2 are set later, if we determine that we are interactive */ | 10448 | /* PS1/PS2/HISTFILE are set later, if we determine that we are interactive */ |
| 10431 | 10449 | ||
| 10432 | /* bash also exports SHLVL and _, | 10450 | /* bash also exports SHLVL and _, |
| 10433 | * and sets (but doesn't export) the following variables: | 10451 | * and sets (but doesn't export) the following variables: |
| @@ -10449,7 +10467,6 @@ int hush_main(int argc, char **argv) | |||
| 10449 | * BASH_SOURCE=() | 10467 | * BASH_SOURCE=() |
| 10450 | * DIRSTACK=() | 10468 | * DIRSTACK=() |
| 10451 | * PIPESTATUS=([0]="0") | 10469 | * PIPESTATUS=([0]="0") |
| 10452 | * HISTFILE=/<xxx>/.bash_history | ||
| 10453 | * HISTFILESIZE=500 | 10470 | * HISTFILESIZE=500 |
| 10454 | * HISTSIZE=500 | 10471 | * HISTSIZE=500 |
| 10455 | * MAILCHECK=60 | 10472 | * MAILCHECK=60 |
| @@ -10809,18 +10826,30 @@ int hush_main(int argc, char **argv) | |||
| 10809 | const char *hp = get_local_var_value("HISTFILE"); | 10826 | const char *hp = get_local_var_value("HISTFILE"); |
| 10810 | if (!hp) { | 10827 | if (!hp) { |
| 10811 | hp = get_local_var_value("HOME"); | 10828 | hp = get_local_var_value("HOME"); |
| 10812 | if (hp) | 10829 | if (hp) { |
| 10813 | hp = concat_path_file(hp, ".hush_history"); | 10830 | hp = concat_path_file(hp, ".hush_history"); |
| 10831 | /* Make HISTFILE set on exit (else history won't be saved) */ | ||
| 10832 | set_local_var_from_halves("HISTFILE", hp); | ||
| 10833 | } | ||
| 10814 | } else { | 10834 | } else { |
| 10815 | hp = xstrdup(hp); | 10835 | hp = xstrdup(hp); |
| 10816 | } | 10836 | } |
| 10817 | if (hp) { | 10837 | if (hp) { |
| 10818 | G.line_input_state->hist_file = hp; | 10838 | G.line_input_state->hist_file = hp; |
| 10819 | //set_local_var(xasprintf("HISTFILE=%s", ...)); | ||
| 10820 | } | 10839 | } |
| 10821 | # if ENABLE_FEATURE_SH_HISTFILESIZE | 10840 | # if ENABLE_FEATURE_SH_HISTFILESIZE |
| 10822 | hp = get_local_var_value("HISTFILESIZE"); | 10841 | hp = get_local_var_value("HISTSIZE"); |
| 10842 | /* Using HISTFILESIZE above to limit max_history would be WRONG: | ||
| 10843 | * users may set HISTFILESIZE=0 in their profile scripts | ||
| 10844 | * to prevent _saving_ of history files, but still want to have | ||
| 10845 | * non-zero history limit for in-memory list. | ||
| 10846 | */ | ||
| 10847 | // in bash, runtime history size is controlled by HISTSIZE (0=no history), | ||
| 10848 | // HISTFILESIZE controls on-disk history file size (in lines, 0=no history): | ||
| 10823 | G.line_input_state->max_history = size_from_HISTFILESIZE(hp); | 10849 | G.line_input_state->max_history = size_from_HISTFILESIZE(hp); |
| 10850 | // HISTFILESIZE: "The shell sets the default value to the value of HISTSIZE after reading any startup files." | ||
| 10851 | // HISTSIZE: "The shell sets the default value to 500 after reading any startup files." | ||
| 10852 | // (meaning: if the value wasn't set after startup files, the default value is set as described above) | ||
| 10824 | # endif | 10853 | # endif |
| 10825 | } | 10854 | } |
| 10826 | # endif | 10855 | # endif |
| @@ -11175,6 +11204,11 @@ static int FAST_FUNC builtin_read(char **argv) | |||
| 11175 | goto again; | 11204 | goto again; |
| 11176 | } | 11205 | } |
| 11177 | 11206 | ||
| 11207 | if ((uintptr_t)r == 2) /* -t SEC timeout? */ | ||
| 11208 | /* bash: "The exit status is greater than 128 if the timeout is exceeded." */ | ||
| 11209 | /* The actual value observed with bash 5.2.15: */ | ||
| 11210 | return 128 + SIGALRM; | ||
| 11211 | |||
| 11178 | if ((uintptr_t)r > 1) { | 11212 | if ((uintptr_t)r > 1) { |
| 11179 | bb_simple_error_msg(r); | 11213 | bb_simple_error_msg(r); |
| 11180 | r = (char*)(uintptr_t)1; | 11214 | r = (char*)(uintptr_t)1; |
diff --git a/shell/hush_test/hush-read/read_t.right b/shell/hush_test/hush-read/read_t.right index 04126cbe6..3eedae275 100644 --- a/shell/hush_test/hush-read/read_t.right +++ b/shell/hush_test/hush-read/read_t.right | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | >< | 1 | >te:142< |
| 2 | >< | 2 | >:142< |
| 3 | >test< | 3 | >test:0< |
| 4 | >test< | 4 | >test:0< |
diff --git a/shell/hush_test/hush-read/read_t.tests b/shell/hush_test/hush-read/read_t.tests index d65f1aeaa..9fbeec517 100755 --- a/shell/hush_test/hush-read/read_t.tests +++ b/shell/hush_test/hush-read/read_t.tests | |||
| @@ -1,10 +1,10 @@ | |||
| 1 | # bash 3.2 outputs: | 1 | # bash 5.2 outputs: |
| 2 | 2 | ||
| 3 | # >< | 3 | # >te:142< |
| 4 | { echo -n 'te'; sleep 2; echo 'st'; } | (read -t 1 reply; echo ">$reply<") | 4 | { echo -n 'te'; sleep 2; echo 'st'; } | (read -t 1 reply; echo ">$reply:$?<") |
| 5 | # >< | 5 | # >:142< |
| 6 | { sleep 2; echo 'test'; } | (read -t 1 reply; echo ">$reply<") | 6 | { sleep 2; echo 'test'; } | (read -t 1 reply; echo ">$reply:$?<") |
| 7 | # >test< | 7 | # >test:0< |
| 8 | { echo -n 'te'; sleep 1; echo 'st'; } | (read -t 2 reply; echo ">$reply<") | 8 | { echo -n 'te'; sleep 1; echo 'st'; } | (read -t 2 reply; echo ">$reply:$?<") |
| 9 | # >test< | 9 | # >test:0< |
| 10 | { sleep 1; echo 'test'; } | (read -t 2 reply; echo ">$reply<") | 10 | { sleep 1; echo 'test'; } | (read -t 2 reply; echo ">$reply:$?<") |
diff --git a/shell/shell_common.c b/shell/shell_common.c index 2702ef98a..657f0df8f 100644 --- a/shell/shell_common.c +++ b/shell/shell_common.c | |||
| @@ -55,7 +55,7 @@ const char* FAST_FUNC | |||
| 55 | shell_builtin_read(struct builtin_read_params *params) | 55 | shell_builtin_read(struct builtin_read_params *params) |
| 56 | { | 56 | { |
| 57 | struct pollfd pfd[1]; | 57 | struct pollfd pfd[1]; |
| 58 | #define fd (pfd[0].fd) /* -u FD */ | 58 | #define fd (pfd->fd) /* -u FD */ |
| 59 | unsigned err; | 59 | unsigned err; |
| 60 | unsigned end_ms; /* -t TIMEOUT */ | 60 | unsigned end_ms; /* -t TIMEOUT */ |
| 61 | int nchars; /* -n NUM */ | 61 | int nchars; /* -n NUM */ |
| @@ -144,7 +144,7 @@ shell_builtin_read(struct builtin_read_params *params) | |||
| 144 | * bash seems to ignore -p PROMPT for this use case. | 144 | * bash seems to ignore -p PROMPT for this use case. |
| 145 | */ | 145 | */ |
| 146 | int r; | 146 | int r; |
| 147 | pfd[0].events = POLLIN; | 147 | pfd->events = POLLIN; |
| 148 | r = poll(pfd, 1, /*timeout:*/ 0); | 148 | r = poll(pfd, 1, /*timeout:*/ 0); |
| 149 | /* Return 0 only if poll returns 1 ("one fd ready"), else return 1: */ | 149 | /* Return 0 only if poll returns 1 ("one fd ready"), else return 1: */ |
| 150 | return (const char *)(uintptr_t)(r <= 0); | 150 | return (const char *)(uintptr_t)(r <= 0); |
| @@ -209,13 +209,8 @@ shell_builtin_read(struct builtin_read_params *params) | |||
| 209 | * 32-bit unix time wrapped (year 2038+). | 209 | * 32-bit unix time wrapped (year 2038+). |
| 210 | */ | 210 | */ |
| 211 | if (timeout <= 0) { /* already late? */ | 211 | if (timeout <= 0) { /* already late? */ |
| 212 | #if ENABLE_PLATFORM_MINGW32 | ||
| 213 | retval = (const char *)(uintptr_t)2; | 212 | retval = (const char *)(uintptr_t)2; |
| 214 | break; | 213 | break; |
| 215 | #else | ||
| 216 | retval = (const char *)(uintptr_t)1; | ||
| 217 | goto ret; | ||
| 218 | #endif | ||
| 219 | } | 214 | } |
| 220 | } | 215 | } |
| 221 | 216 | ||
| @@ -224,8 +219,8 @@ shell_builtin_read(struct builtin_read_params *params) | |||
| 224 | * regardless of SA_RESTART-ness of that signal! | 219 | * regardless of SA_RESTART-ness of that signal! |
| 225 | */ | 220 | */ |
| 226 | errno = 0; | 221 | errno = 0; |
| 227 | pfd[0].events = POLLIN; | 222 | pfd->events = POLLIN; |
| 228 | //TODO race with a signal arriving just before the poll! | 223 | |
| 229 | #if ENABLE_PLATFORM_MINGW32 | 224 | #if ENABLE_PLATFORM_MINGW32 |
| 230 | /* Don't poll if timeout is -1, it hurts performance. The | 225 | /* Don't poll if timeout is -1, it hurts performance. The |
| 231 | * caution above about interrupts isn't relevant on Windows | 226 | * caution above about interrupts isn't relevant on Windows |
| @@ -233,15 +228,14 @@ shell_builtin_read(struct builtin_read_params *params) | |||
| 233 | */ | 228 | */ |
| 234 | if (timeout >= 0) | 229 | if (timeout >= 0) |
| 235 | #endif | 230 | #endif |
| 236 | if (poll(pfd, 1, timeout) <= 0) { | 231 | /* test bb_got_signal, then poll(), atomically wrt signals */ |
| 237 | /* timed out, or EINTR */ | 232 | if (check_got_signal_and_poll(pfd, timeout) <= 0) { |
| 233 | /* timed out, or some error */ | ||
| 238 | err = errno; | 234 | err = errno; |
| 239 | #if ENABLE_PLATFORM_MINGW32 | 235 | if (!err) { /* timed out */ |
| 240 | if (!err) { | ||
| 241 | retval = (const char *)(uintptr_t)2; | 236 | retval = (const char *)(uintptr_t)2; |
| 242 | break; | 237 | break; |
| 243 | } | 238 | } |
| 244 | #endif | ||
| 245 | retval = (const char *)(uintptr_t)1; | 239 | retval = (const char *)(uintptr_t)1; |
| 246 | goto ret; | 240 | goto ret; |
| 247 | } | 241 | } |
