+From 772cc01d3739d50ae43858fed8ec733c0c7bf00c Mon Sep 17 00:00:00 2001
+From: Dennis Groenen <tj.groenen@gmail.com>
+Date: Sun, 21 Aug 2011 13:28:34 +0200
+Subject: [PATCH] add support for delayed history saving
+
+---
+ include/libbb.h | 3 +++
+ libbb/Config.src | 8 ++++++++
+ libbb/lineedit.c | 24 +++++++++++++++++++++++-
+ shell/ash.c | 5 +++++
+ shell/hush.c | 5 +++++
+ 5 files changed, 44 insertions(+), 1 deletions(-)
+
+diff --git a/include/libbb.h b/include/libbb.h
+index 63d0419..233b674 100644
+--- a/include/libbb.h
++++ b/include/libbb.h
+@@ -1446,6 +1446,9 @@ line_input_t *new_line_input_t(int flags) FAST_FUNC;
+ * >0 length of input string, including terminating '\n'
+ */
+ int read_line_input(line_input_t *st, const char *prompt, char *command, int maxsize, int timeout) FAST_FUNC;
++# if ENABLE_FEATURE_EDITING_DELAYEDHISTORY
++void save_history(line_input_t *st);
++# endif
+ #else
+ #define MAX_HISTORY 0
+ int read_line_input(const char* prompt, char* command, int maxsize) FAST_FUNC;
+diff --git a/libbb/Config.src b/libbb/Config.src
+index aa44236..deee15f 100644
+--- a/libbb/Config.src
++++ b/libbb/Config.src
+@@ -94,6 +94,14 @@ config FEATURE_EDITING_SAVEHISTORY
+ help
+ Enable history saving in shells.
+
++config FEATURE_EDITING_DELAYEDHISTORY
++ bool "Delayed history saving"
++ default n
++ depends on FEATURE_EDITING_SAVEHISTORY
++ help
++ Disable saving history to disk after every command. Write out
++ history only upon shell closure instead.
++
+ config FEATURE_REVERSE_SEARCH
+ bool "Reverse history search"
+ default y
+diff --git a/libbb/lineedit.c b/libbb/lineedit.c
+index 1026519..48ac509 100644
+--- a/libbb/lineedit.c
++++ b/libbb/lineedit.c
+@@ -1392,10 +1392,29 @@ static void load_history(line_input_t *st_parm)
+ }
+ }
+
+-/* state->flags is already checked to be nonzero */
++# if ENABLE_FEATURE_EDITING_DELAYEDHISTORY
++void save_history(line_input_t *st)
++# else
+ static void save_history(char *str)
++# endif
+ {
+ int fd;
++# if ENABLE_FEATURE_EDITING_DELAYEDHISTORY
++# if MAX_HISTORY > 0 && ENABLE_FEATURE_EDITING_SAVEHISTORY
++ FILE *f_hist_file;
++ state = st ? st : (line_input_t*) &const_int_0;
++ f_hist_file = fopen(state->hist_file,"a");
++ if (f_hist_file) {
++ int i;
++ for (i = state->cnt_history_in_file; i < state->cnt_history; i++)
++ fprintf(f_hist_file, "%s\n", state->history[i]);
++ }
++ fclose(f_hist_file);
++# else
++ return;
++# endif
++# else
++ /* state->flags is already checked to be nonzero */
+ int len, len2;
+
+ fd = open(state->hist_file, O_WRONLY | O_CREAT | O_APPEND, 0600);
+@@ -1409,6 +1428,7 @@ static void save_history(char *str)
+ close(fd);
+ if (len2 != len + 1)
+ return; /* "wtf?" */
++# endif /* FEATURE_EDITING_DELAYEDHISTORY */
+
+ /* did we write so much that history file needs trimming? */
+ state->cnt_history_in_file++;
+@@ -1475,10 +1495,12 @@ static void remember_in_history(char *str)
+ /* i <= state->max_history */
+ state->cur_history = i;
+ state->cnt_history = i;
++#if !ENABLE_FEATURE_EDITING_DELAYEDHISTORY /* save_history() will be called by exit_shell() */
+ # if MAX_HISTORY > 0 && ENABLE_FEATURE_EDITING_SAVEHISTORY
+ if ((state->flags & SAVE_HISTORY) && state->hist_file)
+ save_history(str);
+ # endif
++#endif
+ IF_FEATURE_EDITING_FANCY_PROMPT(num_ok_lines++;)
+ }
+
+diff --git a/shell/ash.c b/shell/ash.c
+index d48cd01..08d4e92 100644
+--- a/shell/ash.c
++++ b/shell/ash.c
+@@ -12888,6 +12888,11 @@ exitshell(void)
+ char *p;
+ int status;
+
++#if ENABLE_FEATURE_EDITING_DELAYEDHISTORY
++ if ((line_input_state->flags & SAVE_HISTORY) && line_input_state->hist_file)
++ save_history(line_input_state);
++#endif
++
+ status = exitstatus;
+ TRACE(("pid %d, exitshell(%d)\n", getpid(), status));
+ if (setjmp(loc.loc)) {
+diff --git a/shell/hush.c b/shell/hush.c
+index e4138ad..a7428d6 100644
+--- a/shell/hush.c
++++ b/shell/hush.c
+@@ -1541,6 +1541,11 @@ static sighandler_t pick_sighandler(unsigned sig)
+ static void hush_exit(int exitcode) NORETURN;
+ static void hush_exit(int exitcode)
+ {
++#if ENABLE_FEATURE_EDITING_DELAYEDHISTORY
++ if ((G.line_input_state->flags & SAVE_HISTORY) && G.line_input_state->hist_file)
++ save_history(G.line_input_state);
++#endif
++
+ fflush_all();
+ if (G.exiting <= 0 && G.traps && G.traps[0] && G.traps[0][0]) {
+ char *argv[3];
+--
+1.7.6
+