diff options
-rw-r--r-- | gdb/ChangeLog | 11 | ||||
-rw-r--r-- | gdb/event-top.c | 2 | ||||
-rw-r--r-- | gdb/top.c | 73 | ||||
-rw-r--r-- | gdb/top.h | 2 |
4 files changed, 84 insertions, 4 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index b661c54..acbea15f 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,14 @@ +2015-01-12 Patrick Palka <patrick@parcs.ath.cx> + + * top.h (gdb_add_history): Declare. + * top.c (command_count): New variable. + (gdb_add_history): New function. + (gdb_safe_append_history): New static function. + (quit_force): Call it. + (command_line_input): Use gdb_add_history instead of + add_history. + * event-top.c (command_line_handler): Likewise. + 2015-01-12 James Clarke <jrtc27@jrtc27.com> (tiny patch) PR gdb/17046 diff --git a/gdb/event-top.c b/gdb/event-top.c index 13ddee2..bbda5dc 100644 --- a/gdb/event-top.c +++ b/gdb/event-top.c @@ -667,7 +667,7 @@ command_line_handler (char *rl) /* Add line to history if appropriate. */ if (*linebuffer && input_from_terminal_p ()) - add_history (linebuffer); + gdb_add_history (linebuffer); /* Note: lines consisting solely of comments are added to the command history. This is useful when you type a command, and then @@ -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; @@ -79,6 +79,8 @@ extern int history_expansion_p; extern int server_command; extern char *lim_at_start; +extern void gdb_add_history (const char *); + extern void show_commands (char *args, int from_tty); extern void set_history (char *, int); |