ash,hush: optional support for $HISTFILESIZE.
authorDenys Vlasenko <vda.linux@googlemail.com>
Thu, 31 Mar 2011 11:16:52 +0000 (13:16 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Thu, 31 Mar 2011 11:16:52 +0000 (13:16 +0200)
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>
include/libbb.h
libbb/Config.src
libbb/lineedit.c
shell/Config.src
shell/ash.c
shell/hush.c

index c371e35f2b8bf75e81d4d5a7cbbd16d37514d967..f2f3313b41c59137fa3d8b3a5db86d428624d939 100644 (file)
@@ -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;
index a25af23b43561a8cd86d6c35693ec88ceba7ab8e..0ea8f43ab50166e84201b23c43b16877693877ab 100644 (file)
@@ -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"
index b7a2b31dc3dfa28887aaeda50cde76b1a31563a3..095ccfbef97ab34c69fe0471843ab75dfd9192c8 100644 (file)
@@ -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
index e96c21620e557bb7ed85ff9a722ae1326a551fc8..b31e62ddac3ae76b8322baf4c2d17ae9afe6dd3a 100644 (file)
@@ -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
index 1520c5ae5ed20a327ed8351fa09109dbcfb60bc5..11ba9774ae78e5e32a2417cd5878d560fb56ebf2 100644 (file)
@@ -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 */
index e698e6c5222fbac663ac4210f20930be72dd25a8..d3e957c2f2c8ea0490796c19da391ba4534acc01 100644 (file)
@@ -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