aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/libbb.h4
-rw-r--r--libbb/Config.src5
-rw-r--r--libbb/lineedit.c44
-rw-r--r--shell/Config.src10
-rw-r--r--shell/ash.c9
-rw-r--r--shell/hush.c4
6 files changed, 55 insertions, 21 deletions
diff --git a/include/libbb.h b/include/libbb.h
index c371e35f2..f2f3313b4 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -1373,8 +1373,9 @@ void read_key_ungets(char *buffer, const char *str, unsigned len) FAST_FUNC;
#if ENABLE_FEATURE_EDITING
/* It's NOT just ENABLEd or disabled. It's a number: */
-# ifdef CONFIG_FEATURE_EDITING_HISTORY
+# if defined CONFIG_FEATURE_EDITING_HISTORY && CONFIG_FEATURE_EDITING_HISTORY > 0
# define MAX_HISTORY (CONFIG_FEATURE_EDITING_HISTORY + 0)
+unsigned size_from_HISTFILESIZE(const char *hp);
# else
# define MAX_HISTORY 0
# endif
@@ -1384,6 +1385,7 @@ typedef struct line_input_t {
# if MAX_HISTORY
int cnt_history;
int cur_history;
+ int max_history; /* must never be <= 0 */
# if ENABLE_FEATURE_EDITING_SAVEHISTORY
unsigned cnt_history_in_file;
const char *hist_file;
diff --git a/libbb/Config.src b/libbb/Config.src
index a25af23b4..0ea8f43ab 100644
--- a/libbb/Config.src
+++ b/libbb/Config.src
@@ -80,11 +80,12 @@ config FEATURE_EDITING_VI
config FEATURE_EDITING_HISTORY
int "History size"
- range 0 99999
+ # Don't allow way too big values here, code uses fixed "char *history[N]" struct member
+ range 0 9999
default 255
depends on FEATURE_EDITING
help
- Specify command history size.
+ Specify command history size (0 - disable).
config FEATURE_EDITING_SAVEHISTORY
bool "History saving"
diff --git a/libbb/lineedit.c b/libbb/lineedit.c
index b7a2b31dc..095ccfbef 100644
--- a/libbb/lineedit.c
+++ b/libbb/lineedit.c
@@ -1243,12 +1243,26 @@ line_input_t* FAST_FUNC new_line_input_t(int flags)
{
line_input_t *n = xzalloc(sizeof(*n));
n->flags = flags;
+ n->max_history = MAX_HISTORY;
return n;
}
#if MAX_HISTORY > 0
+unsigned size_from_HISTFILESIZE(const char *hp)
+{
+ int size = MAX_HISTORY;
+ if (hp) {
+ size = atoi(hp);
+ if (size <= 0)
+ return 1;
+ if (size > MAX_HISTORY)
+ return MAX_HISTORY;
+ }
+ return size;
+}
+
static void save_command_ps_at_cur_history(void)
{
if (command_ps[0] != BB_NUL) {
@@ -1339,7 +1353,7 @@ static void load_history(line_input_t *st_parm)
temp_h[idx] = line;
st_parm->cnt_history_in_file++;
idx++;
- if (idx == MAX_HISTORY)
+ if (idx == st_parm->max_history)
idx = 0;
}
fclose(fp);
@@ -1348,18 +1362,18 @@ static void load_history(line_input_t *st_parm)
if (st_parm->cnt_history_in_file) {
while (temp_h[idx] == NULL) {
idx++;
- if (idx == MAX_HISTORY)
+ if (idx == st_parm->max_history)
idx = 0;
}
}
/* copy temp_h[] to st_parm->history[] */
- for (i = 0; i < MAX_HISTORY;) {
+ for (i = 0; i < st_parm->max_history;) {
line = temp_h[idx];
if (!line)
break;
idx++;
- if (idx == MAX_HISTORY)
+ if (idx == st_parm->max_history)
idx = 0;
line_len = strlen(line);
if (line_len >= MAX_LINELEN)
@@ -1390,7 +1404,7 @@ static void save_history(char *str)
/* did we write so much that history file needs trimming? */
state->cnt_history_in_file++;
- if (state->cnt_history_in_file > MAX_HISTORY * 4) {
+ if (state->cnt_history_in_file > state->max_history * 4) {
char *new_name;
line_input_t *st_temp;
@@ -1436,20 +1450,20 @@ static void remember_in_history(char *str)
if (i && strcmp(state->history[i-1], str) == 0)
return;
- free(state->history[MAX_HISTORY]); /* redundant, paranoia */
- state->history[MAX_HISTORY] = NULL; /* redundant, paranoia */
+ free(state->history[state->max_history]); /* redundant, paranoia */
+ state->history[state->max_history] = NULL; /* redundant, paranoia */
/* If history[] is full, remove the oldest command */
- /* we need to keep history[MAX_HISTORY] empty, hence >=, not > */
- if (i >= MAX_HISTORY) {
+ /* we need to keep history[state->max_history] empty, hence >=, not > */
+ if (i >= state->max_history) {
free(state->history[0]);
- for (i = 0; i < MAX_HISTORY-1; i++)
+ for (i = 0; i < state->max_history-1; i++)
state->history[i] = state->history[i+1];
- /* i == MAX_HISTORY-1 */
+ /* i == state->max_history-1 */
}
- /* i <= MAX_HISTORY-1 */
+ /* i <= state->max_history-1 */
state->history[i++] = xstrdup(str);
- /* i <= MAX_HISTORY */
+ /* i <= state->max_history */
state->cur_history = i;
state->cnt_history = i;
# if MAX_HISTORY > 0 && ENABLE_FEATURE_EDITING_SAVEHISTORY
@@ -1970,7 +1984,7 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman
maxsize = MAX_LINELEN;
S.maxsize = maxsize;
- /* With null flags, no other fields are ever used */
+ /* With zero flags, no other fields are ever used */
state = st ? st : (line_input_t*) &const_int_0;
#if MAX_HISTORY > 0
# if ENABLE_FEATURE_EDITING_SAVEHISTORY
@@ -2022,7 +2036,7 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman
#endif
#if 0
- for (i = 0; i <= MAX_HISTORY; i++)
+ for (i = 0; i <= state->max_history; i++)
bb_error_msg("history[%d]:'%s'", i, state->history[i]);
bb_error_msg("cur_history:%d cnt_history:%d", state->cur_history, state->cnt_history);
#endif
diff --git a/shell/Config.src b/shell/Config.src
index e96c21620..b31e62dda 100644
--- a/shell/Config.src
+++ b/shell/Config.src
@@ -136,4 +136,14 @@ config FEATURE_SH_NOFORK
This feature is relatively new. Use with care. Report bugs
to project mailing list.
+config FEATURE_SH_HISTFILESIZE
+ bool "Use $HISTFILESIZE"
+ default y
+ depends on HUSH || ASH
+ help
+ This option makes busybox shells to use $HISTFILESIZE variable
+ to set shell history size. Note that its max value is capped
+ by "History size" setting in library tuning section.
+
+
endmenu
diff --git a/shell/ash.c b/shell/ash.c
index 1520c5ae5..11ba9774a 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -13143,10 +13143,9 @@ int ash_main(int argc UNUSED_PARAM, char **argv)
#if ENABLE_FEATURE_EDITING_SAVEHISTORY
if (iflag) {
const char *hp = lookupvar("HISTFILE");
-
- if (hp == NULL) {
+ if (!hp) {
hp = lookupvar("HOME");
- if (hp != NULL) {
+ if (hp) {
char *defhp = concat_path_file(hp, ".ash_history");
setvar("HISTFILE", defhp, 0);
free(defhp);
@@ -13195,6 +13194,10 @@ int ash_main(int argc UNUSED_PARAM, char **argv)
const char *hp = lookupvar("HISTFILE");
if (hp)
line_input_state->hist_file = hp;
+# if ENABLE_FEATURE_SH_HISTFILESIZE
+ hp = lookupvar("HISTFILESIZE");
+ line_input_state->max_history = size_from_HISTFILESIZE(hp);
+# endif
}
#endif
state4: /* XXX ??? - why isn't this before the "if" statement */
diff --git a/shell/hush.c b/shell/hush.c
index e698e6c52..d3e957c2f 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -7614,6 +7614,10 @@ int hush_main(int argc, char **argv)
//set_local_var(xasprintf("HISTFILE=%s", ...));
}
}
+# if ENABLE_FEATURE_SH_HISTFILESIZE
+ hp = get_local_var_value("HISTFILESIZE");
+ G.line_input_state->max_history = size_from_HISTFILESIZE(hp);
+# endif
}
# endif
#endif