return rl_newline (1, key);
}
-\f
+
+/* 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').
/* 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)
{
if (write_history_p && history_filename
&& input_from_terminal_p ())
- write_history (history_filename);
+ gdb_safe_append_history ();
}
DO_PRINT_EX;