| @@ -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++;) |
| } |