aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2016-06-21 01:11:54 +0100
committerPedro Alves <palves@redhat.com>2016-06-21 01:11:54 +0100
commit07169ff772077f566c6540f623d7d609babc4c81 (patch)
tree191ed8266e613017d9341c83976c89f4809cc07b
parent98d9f24ed15c5ca33bff06647d87b85e22e586d2 (diff)
downloadfsf-binutils-gdb-07169ff772077f566c6540f623d7d609babc4c81.zip
fsf-binutils-gdb-07169ff772077f566c6540f623d7d609babc4c81.tar.gz
fsf-binutils-gdb-07169ff772077f566c6540f623d7d609babc4c81.tar.bz2
Handle UI's terminal closing
Without this, GDB exits if a secondary UIs terminal/input stream is closed: $ ./gdb -ex "new-ui mi /dev/pts/6" New UI allocated <<< close /dev/pts/6 (gdb) Error detected on fd 9 $ We want that for the main UI, but not secondary UIs. gdb/ChangeLog: 2016-06-21 Pedro Alves <palves@redhat.com> * event-top.c (stdin_event_handler): Don't quit gdb if it was a secondary UI's input stream that closed. Instead, just delete the UI.
-rw-r--r--gdb/ChangeLog6
-rw-r--r--gdb/event-top.c42
-rw-r--r--gdb/top.c31
-rw-r--r--gdb/top.h1
4 files changed, 65 insertions, 15 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index b21f7c1..22b369d 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,11 @@
2016-06-21 Pedro Alves <palves@redhat.com>
+ * event-top.c (stdin_event_handler): Don't quit gdb if it was a
+ secondary UI's input stream that closed. Instead, just delete the
+ UI.
+
+2016-06-21 Pedro Alves <palves@redhat.com>
+
* event-top.c (main_ui_): Delete.
(main_ui, current_ui, ui_list): No longer initialize here.
* main.c (captured_main): UI initialization code factored out to
diff --git a/gdb/event-top.c b/gdb/event-top.c
index 318da1d..777823e 100644
--- a/gdb/event-top.c
+++ b/gdb/event-top.c
@@ -508,33 +508,45 @@ stdin_event_handler (int error, gdb_client_data client_data)
{
struct ui *ui = (struct ui *) client_data;
- /* Switch to the UI whose input descriptor woke up the event
- loop. */
- current_ui = ui;
-
if (error)
{
- printf_unfiltered (_("error detected on stdin\n"));
+ /* Switch to the main UI, so diagnostics always go there. */
+ current_ui = main_ui;
+
delete_file_handler (ui->input_fd);
- /* If stdin died, we may as well kill gdb. */
- quit_command ((char *) 0, stdin == ui->instream);
+ if (main_ui == ui)
+ {
+ /* If stdin died, we may as well kill gdb. */
+ printf_unfiltered (_("error detected on stdin\n"));
+ quit_command ((char *) 0, stdin == ui->instream);
+ }
+ else
+ {
+ /* Simply delete the UI. */
+ delete_ui (ui);
+ }
}
else
{
- /* This makes sure a ^C immediately followed by further input is
- always processed in that order. E.g,. with input like
- "^Cprint 1\n", the SIGINT handler runs, marks the async signal
- handler, and then select/poll may return with stdin ready,
- instead of -1/EINTR. The
- gdb.base/double-prompt-target-event-error.exp test exercises
- this. */
+ /* Switch to the UI whose input descriptor woke up the event
+ loop. */
+ current_ui = ui;
+
+ /* This makes sure a ^C immediately followed by further input is
+ always processed in that order. E.g,. with input like
+ "^Cprint 1\n", the SIGINT handler runs, marks the async
+ signal handler, and then select/poll may return with stdin
+ ready, instead of -1/EINTR. The
+ gdb.base/double-prompt-target-event-error.exp test exercises
+ this. */
QUIT;
do
{
call_stdin_event_handler_again_p = 0;
ui->call_readline (client_data);
- } while (call_stdin_event_handler_again_p != 0);
+ }
+ while (call_stdin_event_handler_again_p != 0);
}
}
diff --git a/gdb/top.c b/gdb/top.c
index c5e237d..5883875 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -286,6 +286,37 @@ new_ui (FILE *instream, FILE *outstream, FILE *errstream)
return ui;
}
+static void
+free_ui (struct ui *ui)
+{
+ ui_file_delete (ui->m_gdb_stdin);
+ ui_file_delete (ui->m_gdb_stdout);
+ ui_file_delete (ui->m_gdb_stderr);
+
+ xfree (ui);
+}
+
+void
+delete_ui (struct ui *todel)
+{
+ struct ui *ui, *uiprev;
+
+ uiprev = NULL;
+
+ for (ui = ui_list; ui != NULL; uiprev = ui, ui = ui->next)
+ if (ui == todel)
+ break;
+
+ gdb_assert (ui != NULL);
+
+ if (uiprev != NULL)
+ uiprev->next = ui->next;
+ else
+ ui_list = ui->next;
+
+ free_ui (ui);
+}
+
/* Handler for SIGHUP. */
#ifdef SIGHUP
diff --git a/gdb/top.h b/gdb/top.h
index 9766cd5..7fbd187 100644
--- a/gdb/top.h
+++ b/gdb/top.h
@@ -175,6 +175,7 @@ extern void switch_thru_all_uis_next (struct switch_thru_all_uis *state);
/* Create a new UI. */
extern struct ui *new_ui (FILE *instream, FILE *outstream, FILE *errstream);
+extern void delete_ui (struct ui *todel);
/* Cleanup that restores the current UI. */
extern void restore_ui_cleanup (void *data);