Ash writes to ~/.ash_history after every command, causing excessive
wear on devices which use a flash-based device as their storage medium
(i.e. one erase block cycle per command).
This patch allows you to set a temporary location where ash's history
will be saved until the shell is exited.

The patch is a bit hackish, but seems to do its job fine.

Signed-off-by: Dennis Groenen <[email protected]>
---
 shell/ash.c |   51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 51 insertions(+), 0 deletions(-)

diff --git a/shell/ash.c b/shell/ash.c
index d48cd01..940dfe9 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -184,6 +184,24 @@
 //config:        This option recreates the prompt string from the environment
 //config:        variable each time it is displayed.
 //config:
+//config:config ASH_HIST_BUFFER
+//config:      bool "History buffer"
+//config:      default n
+//config:      depends on ASH && FEATURE_EDITING_SAVEHISTORY
+//config:      help
+//config:        Allows you to set a temporary location for .ash_history.
+//config:        History is saved to this custom location, and written out to
+//config:        its default location (~/.ash_history) upon shell exit.
+//config:        Useful to prevent wear on flash-based storage devices.
+//config:
+//config:config ASH_HIST_BUFFER_PATH
+//config:      string "History buffer location"
+//config:      default "/tmp"
+//config:      depends on ASH && ASH_HIST_BUFFER
+//config:      help
+//config:        Directory which will be used to save the shell history until
+//config:        ash is exited.
+//config:

 //applet:IF_ASH(APPLET(ash, BB_DIR_BIN, BB_SUID_DROP))
 //applet:IF_FEATURE_SH_IS_ASH(APPLET_ODDNAME(sh, ash, BB_DIR_BIN,
BB_SUID_DROP, sh))
@@ -12888,6 +12906,14 @@ exitshell(void)
        char *p;
        int status;

+#if ENABLE_ASH_HIST_BUFFER
+       const char *tmphistory = lookupvar("HISTFILE");
+       const char *storedhistory = lookupvar("STOREDHISTFILE");
+
+       if (access(tmphistory, R_OK) == 0)
+               copy_file(tmphistory, storedhistory, 11); /* 11 = force copy &
preserve permissions */
+#endif
+
        status = exitstatus;
        TRACE(("pid %d, exitshell(%d)\n", getpid(), status));
        if (setjmp(loc.loc)) {
@@ -13151,9 +13177,34 @@ int ash_main(int argc UNUSED_PARAM, char **argv)
                if (!hp) {
                        hp = lookupvar("HOME");
                        if (hp) {
+#if ENABLE_ASH_HIST_BUFFER
+                               char *tmphistory;
+                               char *storedhistory;
+                               const char *user = lookupvar("USER");
+
+                               if (access(CONFIG_ASH_HIST_BUFFER_PATH, R_OK == 
-1))
+                                       bb_make_directory(xasprintf("%s", 
CONFIG_ASH_HIST_BUFFER_PATH),
01777, FILEUTILS_RECUR);
+
+                               tmphistory = 
concat_path_file(CONFIG_ASH_HIST_BUFFER_PATH,
+                                       xasprintf(".ash_hist_%s", user));
+                               storedhistory = concat_path_file(hp, 
".ash_history");
+
+                               /* Create ~/.ash_history if non-existant */
+                               if (access(storedhistory, R_OK) == -1)
+                                       close(open(storedhistory, O_WRONLY | 
O_CREAT, 0644));
+                               /* Copy stored history to buffer locaton if the 
latter is non-existant */
+                               if (access(tmphistory, R_OK | W_OK) == -1)
+                                       copy_file(storedhistory, tmphistory, 
11); /* 11 = force copy &
preserve permissions */
+
+                               setvar("HISTFILE", tmphistory, 0);
+                               setvar("STOREDHISTFILE", storedhistory, 0);
+                               free(storedhistory);
+                               free(tmphistory);
+#else
                                char *defhp = concat_path_file(hp, 
".ash_history");
                                setvar("HISTFILE", defhp, 0);
                                free(defhp);
+#endif
                        }
                }
        }
-- 
1.7.6
_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to