aboutsummaryrefslogtreecommitdiff
path: root/shell/hush.c
diff options
context:
space:
mode:
Diffstat (limited to 'shell/hush.c')
-rw-r--r--shell/hush.c53
1 files changed, 46 insertions, 7 deletions
diff --git a/shell/hush.c b/shell/hush.c
index 4a97293cc..d1f687f9d 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
2102static 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. */
2103static void hush_exit(int exitcode) 2105static 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();
@@ -4607,6 +4625,11 @@ static int fetch_heredocs(o_string *as_string, struct pipe *pi, int heredoc_cnt,
4607 4625
4608 redir->rd_type = REDIRECT_HEREDOC2; 4626 redir->rd_type = REDIRECT_HEREDOC2;
4609 /* redir->rd_dup is (ab)used to indicate <<- */ 4627 /* redir->rd_dup is (ab)used to indicate <<- */
4628 if (!redir->rd_filename) {
4629 /* examples: "echo <<", "echo <<<", "echo <<>" */
4630 syntax_error("missing here document terminator");
4631 return -1;
4632 }
4610 p = fetch_till_str(as_string, input, 4633 p = fetch_till_str(as_string, input,
4611 redir->rd_filename, redir->rd_dup); 4634 redir->rd_filename, redir->rd_dup);
4612 if (!p) { 4635 if (!p) {
@@ -10427,7 +10450,7 @@ int hush_main(int argc, char **argv)
10427 if (!get_local_var_value("PATH")) 10450 if (!get_local_var_value("PATH"))
10428 set_local_var_from_halves("PATH", bb_default_root_path); 10451 set_local_var_from_halves("PATH", bb_default_root_path);
10429 10452
10430 /* PS1/PS2 are set later, if we determine that we are interactive */ 10453 /* PS1/PS2/HISTFILE are set later, if we determine that we are interactive */
10431 10454
10432 /* bash also exports SHLVL and _, 10455 /* bash also exports SHLVL and _,
10433 * and sets (but doesn't export) the following variables: 10456 * and sets (but doesn't export) the following variables:
@@ -10449,7 +10472,6 @@ int hush_main(int argc, char **argv)
10449 * BASH_SOURCE=() 10472 * BASH_SOURCE=()
10450 * DIRSTACK=() 10473 * DIRSTACK=()
10451 * PIPESTATUS=([0]="0") 10474 * PIPESTATUS=([0]="0")
10452 * HISTFILE=/<xxx>/.bash_history
10453 * HISTFILESIZE=500 10475 * HISTFILESIZE=500
10454 * HISTSIZE=500 10476 * HISTSIZE=500
10455 * MAILCHECK=60 10477 * MAILCHECK=60
@@ -10809,18 +10831,30 @@ int hush_main(int argc, char **argv)
10809 const char *hp = get_local_var_value("HISTFILE"); 10831 const char *hp = get_local_var_value("HISTFILE");
10810 if (!hp) { 10832 if (!hp) {
10811 hp = get_local_var_value("HOME"); 10833 hp = get_local_var_value("HOME");
10812 if (hp) 10834 if (hp) {
10813 hp = concat_path_file(hp, ".hush_history"); 10835 hp = concat_path_file(hp, ".hush_history");
10836 /* Make HISTFILE set on exit (else history won't be saved) */
10837 set_local_var_from_halves("HISTFILE", hp);
10838 }
10814 } else { 10839 } else {
10815 hp = xstrdup(hp); 10840 hp = xstrdup(hp);
10816 } 10841 }
10817 if (hp) { 10842 if (hp) {
10818 G.line_input_state->hist_file = hp; 10843 G.line_input_state->hist_file = hp;
10819 //set_local_var(xasprintf("HISTFILE=%s", ...));
10820 } 10844 }
10821# if ENABLE_FEATURE_SH_HISTFILESIZE 10845# if ENABLE_FEATURE_SH_HISTFILESIZE
10822 hp = get_local_var_value("HISTFILESIZE"); 10846 hp = get_local_var_value("HISTSIZE");
10847 /* Using HISTFILESIZE above to limit max_history would be WRONG:
10848 * users may set HISTFILESIZE=0 in their profile scripts
10849 * to prevent _saving_ of history files, but still want to have
10850 * non-zero history limit for in-memory list.
10851 */
10852// in bash, runtime history size is controlled by HISTSIZE (0=no history),
10853// HISTFILESIZE controls on-disk history file size (in lines, 0=no history):
10823 G.line_input_state->max_history = size_from_HISTFILESIZE(hp); 10854 G.line_input_state->max_history = size_from_HISTFILESIZE(hp);
10855// HISTFILESIZE: "The shell sets the default value to the value of HISTSIZE after reading any startup files."
10856// HISTSIZE: "The shell sets the default value to 500 after reading any startup files."
10857// (meaning: if the value wasn't set after startup files, the default value is set as described above)
10824# endif 10858# endif
10825 } 10859 }
10826# endif 10860# endif
@@ -11175,6 +11209,11 @@ static int FAST_FUNC builtin_read(char **argv)
11175 goto again; 11209 goto again;
11176 } 11210 }
11177 11211
11212 if ((uintptr_t)r == 2) /* -t SEC timeout? */
11213 /* bash: "The exit status is greater than 128 if the timeout is exceeded." */
11214 /* The actual value observed with bash 5.2.15: */
11215 return 128 + SIGALRM;
11216
11178 if ((uintptr_t)r > 1) { 11217 if ((uintptr_t)r > 1) {
11179 bb_simple_error_msg(r); 11218 bb_simple_error_msg(r);
11180 r = (char*)(uintptr_t)1; 11219 r = (char*)(uintptr_t)1;