This is the mail archive of the gdb-cvs@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] Handle UI's terminal closing


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=07169ff772077f566c6540f623d7d609babc4c81

commit 07169ff772077f566c6540f623d7d609babc4c81
Author: Pedro Alves <palves@redhat.com>
Date:   Tue Jun 21 01:11:54 2016 +0100

    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.

Diff:
---
 gdb/ChangeLog   |  6 ++++++
 gdb/event-top.c | 42 +++++++++++++++++++++++++++---------------
 gdb/top.c       | 31 +++++++++++++++++++++++++++++++
 gdb/top.h       |  1 +
 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);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]