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.
This commit is contained in:
Pedro Alves 2016-06-21 01:11:54 +01:00
parent 98d9f24ed1
commit 07169ff772
4 changed files with 65 additions and 15 deletions

View File

@ -1,3 +1,9 @@
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.

View File

@ -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);
}
}

View File

@ -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

View File

@ -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);