diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2025-07-03 19:10:42 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2025-07-03 19:10:42 +0200 |
| commit | 9c46a0688576dd8c67d2fc24b68c07402da14fc8 (patch) | |
| tree | 1dacd2f246a2010dd84f691c55b0d38bbcded093 /shell | |
| parent | 36ac283682bb176987c0c09e5f8c7e7e96fb1651 (diff) | |
| download | busybox-w32-9c46a0688576dd8c67d2fc24b68c07402da14fc8.tar.gz busybox-w32-9c46a0688576dd8c67d2fc24b68c07402da14fc8.tar.bz2 busybox-w32-9c46a0688576dd8c67d2fc24b68c07402da14fc8.zip | |
shell: update HISTFILESIZE code to be actually useful
"HISTFILESIZE=0" in profile wasn't working as intended,
"unset HISTFILE" wasn't preventing creation of history files
Now:
HISTSIZE=n allows to reduce in-memory history buffer
HISTFILESIZE=n allows to reduce history file size (0: truncate it)
unset HISTFILE allows to not save history file at all
function old new delta
exitshell 138 194 +56
hush_exit 97 143 +46
save_history 266 296 +30
hush_main 1170 1186 +16
.rodata 105762 105771 +9
load_history 246 254 +8
size_from_HISTFILESIZE 44 41 -3
read_line_input 2746 2712 -34
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 6/2 up/down: 165/-37) Total: 128 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/Config.src | 7 | ||||
| -rw-r--r-- | shell/ash.c | 26 | ||||
| -rw-r--r-- | shell/hush.c | 41 |
3 files changed, 63 insertions, 11 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 16eb88a7b..18344767a 100644 --- a/shell/ash.c +++ b/shell/ash.c | |||
| @@ -14525,8 +14525,25 @@ exitshell(void) | |||
| 14525 | char *p; | 14525 | char *p; |
| 14526 | 14526 | ||
| 14527 | #if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT | 14527 | #if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT |
| 14528 | save_history(line_input_state); /* may be NULL */ | 14528 | if (line_input_state) { |
| 14529 | const char *hp; | ||
| 14530 | # if ENABLE_FEATURE_SH_HISTFILESIZE | ||
| 14531 | // in bash: | ||
| 14532 | // HISTFILESIZE controls the on-disk history file size (in lines, 0=no history): | ||
| 14533 | // "When this variable is assigned a value, the history file is truncated, if necessary" | ||
| 14534 | // but we do it only at exit, not on assignment: | ||
| 14535 | /* Use HISTFILESIZE to limit file size */ | ||
| 14536 | hp = lookupvar("HISTFILESIZE"); | ||
| 14537 | if (hp) | ||
| 14538 | line_input_state->max_history = size_from_HISTFILESIZE(hp); | ||
| 14539 | # endif | ||
| 14540 | /* HISTFILE: "If unset, the command history is not saved when a shell exits." */ | ||
| 14541 | hp = lookupvar("HISTFILE"); | ||
| 14542 | line_input_state->hist_file = hp; | ||
| 14543 | save_history(line_input_state); /* no-op if hist_file is NULL */ | ||
| 14544 | } | ||
| 14529 | #endif | 14545 | #endif |
| 14546 | |||
| 14530 | savestatus = exitstatus; | 14547 | savestatus = exitstatus; |
| 14531 | TRACE(("pid %d, exitshell(%d)\n", getpid(), savestatus)); | 14548 | TRACE(("pid %d, exitshell(%d)\n", getpid(), savestatus)); |
| 14532 | if (setjmp(loc.loc)) | 14549 | if (setjmp(loc.loc)) |
| @@ -14867,7 +14884,12 @@ int ash_main(int argc UNUSED_PARAM, char **argv) | |||
| 14867 | if (hp) | 14884 | if (hp) |
| 14868 | line_input_state->hist_file = xstrdup(hp); | 14885 | line_input_state->hist_file = xstrdup(hp); |
| 14869 | # if ENABLE_FEATURE_SH_HISTFILESIZE | 14886 | # if ENABLE_FEATURE_SH_HISTFILESIZE |
| 14870 | hp = lookupvar("HISTFILESIZE"); | 14887 | hp = lookupvar("HISTSIZE"); |
| 14888 | /* Using HISTFILESIZE above to limit max_history would be WRONG: | ||
| 14889 | * users may set HISTFILESIZE=0 in their profile scripts | ||
| 14890 | * to prevent _saving_ of history files, but still want to have | ||
| 14891 | * non-zero history limit for in-memory list. | ||
| 14892 | */ | ||
| 14871 | line_input_state->max_history = size_from_HISTFILESIZE(hp); | 14893 | line_input_state->max_history = size_from_HISTFILESIZE(hp); |
| 14872 | # endif | 14894 | # endif |
| 14873 | } | 14895 | } |
diff --git a/shell/hush.c b/shell/hush.c index 70b730f67..68aca53a3 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
| @@ -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 */ | ||
| 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 |
