aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2011-09-04 16:12:33 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2011-09-04 16:12:33 +0200
commitbede215cf105377a1127532d2d710924cb58cc39 (patch)
treed0227961b7eb002cb03653f2e69211e6cf13d598 /libbb
parent4840ae8a06298e987374fa3cc6d7e4969fd19344 (diff)
downloadbusybox-bede215cf105377a1127532d2d710924cb58cc39.tar.gz
lineedit: add support for history saving on exit
Based on the patch by Dennis Groenen <tj.groenen@gmail.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'libbb')
-rw-r--r--libbb/Config.src7
-rw-r--r--libbb/lineedit.c68
2 files changed, 69 insertions, 6 deletions
diff --git a/libbb/Config.src b/libbb/Config.src
index aa442365a..f6f88b9ce 100644
--- a/libbb/Config.src
+++ b/libbb/Config.src
@@ -94,6 +94,13 @@ config FEATURE_EDITING_SAVEHISTORY
help
Enable history saving in shells.
+config FEATURE_EDITING_SAVE_ON_EXIT
+ bool "Save history on shell exit, not after every command"
+ default n
+ depends on FEATURE_EDITING_SAVEHISTORY
+ help
+ Save history on shell exit, not after every command.
+
config FEATURE_REVERSE_SEARCH
bool "Reverse history search"
default y
diff --git a/libbb/lineedit.c b/libbb/lineedit.c
index 5d139043a..0786f9ae6 100644
--- a/libbb/lineedit.c
+++ b/libbb/lineedit.c
@@ -1351,7 +1351,9 @@ static void load_history(line_input_t *st_parm)
/* fill temp_h[], retaining only last MAX_HISTORY lines */
memset(temp_h, 0, sizeof(temp_h));
- st_parm->cnt_history_in_file = idx = 0;
+ idx = 0;
+ if (!ENABLE_FEATURE_EDITING_SAVE_ON_EXIT)
+ st_parm->cnt_history_in_file = 0;
while ((line = xmalloc_fgetline(fp)) != NULL) {
if (line[0] == '\0') {
free(line);
@@ -1359,7 +1361,8 @@ static void load_history(line_input_t *st_parm)
}
free(temp_h[idx]);
temp_h[idx] = line;
- st_parm->cnt_history_in_file++;
+ if (!ENABLE_FEATURE_EDITING_SAVE_ON_EXIT)
+ st_parm->cnt_history_in_file++;
idx++;
if (idx == st_parm->max_history)
idx = 0;
@@ -1389,15 +1392,66 @@ static void load_history(line_input_t *st_parm)
st_parm->history[i++] = line;
}
st_parm->cnt_history = i;
+ if (ENABLE_FEATURE_EDITING_SAVE_ON_EXIT)
+ st_parm->cnt_history_in_file = i;
}
}
-/* state->flags is already checked to be nonzero */
+# if ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
+void save_history(line_input_t *st)
+{
+ FILE *fp;
+
+ if (!(st->flags & SAVE_HISTORY))
+ return;
+ if (!st->hist_file)
+ return;
+ if (st->cnt_history <= st->cnt_history_in_file)
+ return;
+
+ fp = fopen(st->hist_file, "a");
+ if (fp) {
+ int i, fd;
+ char *new_name;
+ line_input_t *st_temp;
+
+ for (i = st->cnt_history_in_file; i < st->cnt_history; i++)
+ fprintf(fp, "%s\n", st->history[i]);
+ fclose(fp);
+
+ /* we may have concurrently written entries from others.
+ * load them */
+ st_temp = new_line_input_t(st->flags);
+ st_temp->hist_file = st->hist_file;
+ st_temp->max_history = st->max_history;
+ load_history(st_temp);
+
+ /* write out temp file and replace hist_file atomically */
+ new_name = xasprintf("%s.%u.new", st->hist_file, (int) getpid());
+ fd = open(new_name, O_WRONLY | O_CREAT | O_TRUNC, 0600);
+ if (fd >= 0) {
+ fp = xfdopen_for_write(fd);
+ for (i = 0; i < st_temp->cnt_history; i++)
+ fprintf(fp, "%s\n", st_temp->history[i]);
+ fclose(fp);
+ if (rename(new_name, st->hist_file) == 0)
+ st->cnt_history_in_file = st_temp->cnt_history;
+ }
+ free(new_name);
+ free_line_input_t(st_temp);
+ }
+}
+# else
static void save_history(char *str)
{
int fd;
int len, len2;
+ if (!(state->flags & SAVE_HISTORY))
+ return;
+ if (!state->hist_file)
+ return;
+
fd = open(state->hist_file, O_WRONLY | O_CREAT | O_APPEND, 0600);
if (fd < 0)
return;
@@ -1441,6 +1495,7 @@ static void save_history(char *str)
free_line_input_t(st_temp);
}
}
+# endif
# else
# define load_history(a) ((void)0)
# define save_history(a) ((void)0)
@@ -1469,15 +1524,16 @@ static void remember_in_history(char *str)
for (i = 0; i < state->max_history-1; i++)
state->history[i] = state->history[i+1];
/* i == state->max_history-1 */
+ if (ENABLE_FEATURE_EDITING_SAVE_ON_EXIT && state->cnt_history_in_file)
+ state->cnt_history_in_file--;
}
/* i <= state->max_history-1 */
state->history[i++] = xstrdup(str);
/* i <= state->max_history */
state->cur_history = i;
state->cnt_history = i;
-# if ENABLE_FEATURE_EDITING_SAVEHISTORY
- if ((state->flags & SAVE_HISTORY) && state->hist_file)
- save_history(str);
+# if ENABLE_FEATURE_EDITING_SAVEHISTORY && !ENABLE_FEATURE_EDITING_SAVE_ON_EXIT
+ save_history(str);
# endif
IF_FEATURE_EDITING_FANCY_PROMPT(num_ok_lines++;)
}