[PATCH] ash: add support for history buffer
Dennis Groenen
tj.groenen at gmail.com
Mon Jul 11 16:27:18 UTC 2011
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 <tj.groenen at gmail.com>
---
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
More information about the busybox
mailing list