aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2025-07-03 19:10:42 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2025-07-03 19:10:42 +0200
commit9c46a0688576dd8c67d2fc24b68c07402da14fc8 (patch)
tree1dacd2f246a2010dd84f691c55b0d38bbcded093 /shell
parent36ac283682bb176987c0c09e5f8c7e7e96fb1651 (diff)
downloadbusybox-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.src7
-rw-r--r--shell/ash.c26
-rw-r--r--shell/hush.c41
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
173config FEATURE_SH_EMBEDDED_SCRIPTS 174config 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
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 */
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