diff options
Diffstat (limited to 'gdb/top.c')
-rw-r--r-- | gdb/top.c | 73 |
1 files changed, 70 insertions, 3 deletions
@@ -895,7 +895,74 @@ gdb_rl_operate_and_get_next (int count, int key) return rl_newline (1, key); } - + +/* Number of user commands executed during this session. */ + +static int command_count = 0; + +/* Add the user command COMMAND to the input history list. */ + +void +gdb_add_history (const char *command) +{ + add_history (command); + command_count++; +} + +/* Safely append new history entries to the history file in a corruption-free + way using an intermediate local history file. */ + +static void +gdb_safe_append_history (void) +{ + int ret, saved_errno; + char *local_history_filename; + struct cleanup *old_chain; + + local_history_filename + = xstrprintf ("%s-gdb%d~", history_filename, getpid ()); + old_chain = make_cleanup (xfree, local_history_filename); + + ret = rename (history_filename, local_history_filename); + saved_errno = errno; + if (ret < 0 && saved_errno != ENOENT) + { + warning (_("Could not rename %s to %s: %s"), + history_filename, local_history_filename, + safe_strerror (saved_errno)); + } + else + { + if (ret < 0) + { + /* If the rename failed with ENOENT then either the global history + file never existed in the first place or another GDB process is + currently appending to it (and has thus temporarily renamed it). + Since we can't distinguish between these two cases, we have to + conservatively assume the first case and therefore must write out + (not append) our known history to our local history file and try + to move it back anyway. Otherwise a global history file would + never get created! */ + gdb_assert (saved_errno == ENOENT); + write_history (local_history_filename); + } + else + { + append_history (command_count, local_history_filename); + history_truncate_file (local_history_filename, history_max_entries); + } + + ret = rename (local_history_filename, history_filename); + saved_errno = errno; + if (ret < 0 && saved_errno != EEXIST) + warning (_("Could not rename %s to %s: %s"), + local_history_filename, history_filename, + safe_strerror (saved_errno)); + } + + do_cleanups (old_chain); +} + /* Read one line from the command input stream `instream' into the local static buffer `linebuffer' (whose current length is `linelength'). @@ -1094,7 +1161,7 @@ command_line_input (const char *prompt_arg, int repeat, char *annotation_suffix) /* Add line to history if appropriate. */ if (*linebuffer && input_from_terminal_p ()) - add_history (linebuffer); + gdb_add_history (linebuffer); /* Save into global buffer if appropriate. */ if (repeat) @@ -1445,7 +1512,7 @@ quit_force (char *args, int from_tty) { if (write_history_p && history_filename && input_from_terminal_p ()) - write_history (history_filename); + gdb_safe_append_history (); } DO_PRINT_EX; |