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
