ash,hush: optional support for $HISTFILESIZE.

Based on patch from Alexey Fomenko (ext-alexey.fomenko AT nokia.com)

function                                             old     new   delta
size_from_HISTFILESIZE                                 -      44     +44
hush_main                                            998    1025     +27
ash_main                                            1348    1374     +26
read_line_input                                     3361    3372     +11
new_line_input_t                                      17      24      +7

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2011-03-31 13:16:52 +02:00
parent a439fa93f6
commit 2c4de5b045
6 changed files with 55 additions and 21 deletions

View File

@ -1373,8 +1373,9 @@ void read_key_ungets(char *buffer, const char *str, unsigned len) FAST_FUNC;
#if ENABLE_FEATURE_EDITING #if ENABLE_FEATURE_EDITING
/* It's NOT just ENABLEd or disabled. It's a number: */ /* 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) # define MAX_HISTORY (CONFIG_FEATURE_EDITING_HISTORY + 0)
unsigned size_from_HISTFILESIZE(const char *hp);
# else # else
# define MAX_HISTORY 0 # define MAX_HISTORY 0
# endif # endif
@ -1384,6 +1385,7 @@ typedef struct line_input_t {
# if MAX_HISTORY # if MAX_HISTORY
int cnt_history; int cnt_history;
int cur_history; int cur_history;
int max_history; /* must never be <= 0 */
# if ENABLE_FEATURE_EDITING_SAVEHISTORY # if ENABLE_FEATURE_EDITING_SAVEHISTORY
unsigned cnt_history_in_file; unsigned cnt_history_in_file;
const char *hist_file; const char *hist_file;

View File

@ -80,11 +80,12 @@ config FEATURE_EDITING_VI
config FEATURE_EDITING_HISTORY config FEATURE_EDITING_HISTORY
int "History size" 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 default 255
depends on FEATURE_EDITING depends on FEATURE_EDITING
help help
Specify command history size. Specify command history size (0 - disable).
config FEATURE_EDITING_SAVEHISTORY config FEATURE_EDITING_SAVEHISTORY
bool "History saving" bool "History saving"

View File

@ -1243,12 +1243,26 @@ line_input_t* FAST_FUNC new_line_input_t(int flags)
{ {
line_input_t *n = xzalloc(sizeof(*n)); line_input_t *n = xzalloc(sizeof(*n));
n->flags = flags; n->flags = flags;
n->max_history = MAX_HISTORY;
return n; return n;
} }
#if MAX_HISTORY > 0 #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) static void save_command_ps_at_cur_history(void)
{ {
if (command_ps[0] != BB_NUL) { if (command_ps[0] != BB_NUL) {
@ -1339,7 +1353,7 @@ static void load_history(line_input_t *st_parm)
temp_h[idx] = line; temp_h[idx] = line;
st_parm->cnt_history_in_file++; st_parm->cnt_history_in_file++;
idx++; idx++;
if (idx == MAX_HISTORY) if (idx == st_parm->max_history)
idx = 0; idx = 0;
} }
fclose(fp); fclose(fp);
@ -1348,18 +1362,18 @@ static void load_history(line_input_t *st_parm)
if (st_parm->cnt_history_in_file) { if (st_parm->cnt_history_in_file) {
while (temp_h[idx] == NULL) { while (temp_h[idx] == NULL) {
idx++; idx++;
if (idx == MAX_HISTORY) if (idx == st_parm->max_history)
idx = 0; idx = 0;
} }
} }
/* copy temp_h[] to st_parm->history[] */ /* 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]; line = temp_h[idx];
if (!line) if (!line)
break; break;
idx++; idx++;
if (idx == MAX_HISTORY) if (idx == st_parm->max_history)
idx = 0; idx = 0;
line_len = strlen(line); line_len = strlen(line);
if (line_len >= MAX_LINELEN) 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? */ /* did we write so much that history file needs trimming? */
state->cnt_history_in_file++; 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; char *new_name;
line_input_t *st_temp; 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) if (i && strcmp(state->history[i-1], str) == 0)
return; return;
free(state->history[MAX_HISTORY]); /* redundant, paranoia */ free(state->history[state->max_history]); /* redundant, paranoia */
state->history[MAX_HISTORY] = NULL; /* redundant, paranoia */ state->history[state->max_history] = NULL; /* redundant, paranoia */
/* If history[] is full, remove the oldest command */ /* If history[] is full, remove the oldest command */
/* we need to keep history[MAX_HISTORY] empty, hence >=, not > */ /* we need to keep history[state->max_history] empty, hence >=, not > */
if (i >= MAX_HISTORY) { if (i >= state->max_history) {
free(state->history[0]); 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]; 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); state->history[i++] = xstrdup(str);
/* i <= MAX_HISTORY */ /* i <= state->max_history */
state->cur_history = i; state->cur_history = i;
state->cnt_history = i; state->cnt_history = i;
# if MAX_HISTORY > 0 && ENABLE_FEATURE_EDITING_SAVEHISTORY # 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; maxsize = MAX_LINELEN;
S.maxsize = maxsize; 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; state = st ? st : (line_input_t*) &const_int_0;
#if MAX_HISTORY > 0 #if MAX_HISTORY > 0
# if ENABLE_FEATURE_EDITING_SAVEHISTORY # 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 #endif
#if 0 #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("history[%d]:'%s'", i, state->history[i]);
bb_error_msg("cur_history:%d cnt_history:%d", state->cur_history, state->cnt_history); bb_error_msg("cur_history:%d cnt_history:%d", state->cur_history, state->cnt_history);
#endif #endif

View File

@ -136,4 +136,14 @@ config FEATURE_SH_NOFORK
This feature is relatively new. Use with care. Report bugs This feature is relatively new. Use with care. Report bugs
to project mailing list. 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 endmenu

View File

@ -13143,10 +13143,9 @@ int ash_main(int argc UNUSED_PARAM, char **argv)
#if ENABLE_FEATURE_EDITING_SAVEHISTORY #if ENABLE_FEATURE_EDITING_SAVEHISTORY
if (iflag) { if (iflag) {
const char *hp = lookupvar("HISTFILE"); const char *hp = lookupvar("HISTFILE");
if (!hp) {
if (hp == NULL) {
hp = lookupvar("HOME"); hp = lookupvar("HOME");
if (hp != NULL) { if (hp) {
char *defhp = concat_path_file(hp, ".ash_history"); char *defhp = concat_path_file(hp, ".ash_history");
setvar("HISTFILE", defhp, 0); setvar("HISTFILE", defhp, 0);
free(defhp); free(defhp);
@ -13195,6 +13194,10 @@ int ash_main(int argc UNUSED_PARAM, char **argv)
const char *hp = lookupvar("HISTFILE"); const char *hp = lookupvar("HISTFILE");
if (hp) if (hp)
line_input_state->hist_file = 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 #endif
state4: /* XXX ??? - why isn't this before the "if" statement */ state4: /* XXX ??? - why isn't this before the "if" statement */

View File

@ -7614,6 +7614,10 @@ int hush_main(int argc, char **argv)
//set_local_var(xasprintf("HISTFILE=%s", ...)); //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
#endif #endif