mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 20:14:06 +08:00
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:
parent
98d9f24ed1
commit
07169ff772
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
31
gdb/top.c
31
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
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user