+2016-06-21 Pedro Alves <palves@redhat.com>
+
+ * event-top.c (input_fd): Delete.
+ (stdin_event_handler): Switch to the UI whose input descriptor got
+ the event. Adjust to per-UI input_fd.
+ (gdb_setup_readline): Don't set the input_fd global. Adjust to
+ per-UI input_fd.
+ (gdb_disable_readline): Adjust to per-UI input_fd.
+ * event-top.h (input_fd): Delete declaration.
+ * linux-nat.c (linux_nat_terminal_inferior): Don't remove input_fd
+ from the event-loop here.
+ (linux_nat_terminal_ours): Don't register input_fd in the
+ event-loop here.
+ * main.c (captured_main): Adjust to per-UI input_fd.
+ * remote.c (remote_terminal_inferior): Don't remove input_fd from
+ the event-loop here.
+ (remote_terminal_ours): Don't register input_fd in the event-loop
+ here.
+ * target.c: Include top.h and event-top.h.
+ (target_terminal_inferior): Remove input_fd from the event-loop
+ here.
+ (target_terminal_ours): Register input_fd in the event-loop.
+ * top.h (struct ui) <input_fd>: New field.
+
2016-06-21 Pedro Alves <palves@redhat.com>
* cli/cli-script.c (execute_user_command, read_next_line)
asynchronous execution command. */
int exec_done_display_p = 0;
-/* This is the file descriptor for the input stream that GDB uses to
- read commands from. */
-int input_fd;
-
/* Used by the stdin event handler to compensate for missed stdin events.
Setting this to a non-zero value inside an stdin callback makes the callback
run again. */
void
stdin_event_handler (int error, gdb_client_data client_data)
{
- struct ui *ui = current_ui;
+ 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"));
- delete_file_handler (input_fd);
+ delete_file_handler (ui->input_fd);
/* If stdin died, we may as well kill gdb. */
quit_command ((char *) 0, stdin == ui->instream);
}
/* Tell readline to use the same input stream that gdb uses. */
rl_instream = ui->instream;
- /* Get a file descriptor for the input stream, so that we can
- register it with the event loop. */
- input_fd = fileno (ui->instream);
-
- /* Now we need to create the event sources for the input file
- descriptor. */
- /* At this point in time, this is the only event source that we
- register with the even loop. Another source is going to be the
- target program (inferior), but that must be registered only when
- it actually exists (I.e. after we say 'run' or after we connect
- to a remote target. */
- add_file_handler (input_fd, stdin_event_handler, 0);
+ /* Now create the event source for this UI's input file descriptor.
+ Another source is going to be the target program (inferior), but
+ that must be registered only when it actually exists (I.e. after
+ we say 'run' or after we connect to a remote target. */
+ add_file_handler (ui->input_fd, stdin_event_handler, ui);
}
/* Disable command input through the standard CLI channels. Used in
void
gdb_disable_readline (void)
{
+ struct ui *ui = current_ui;
+
/* FIXME - It is too heavyweight to delete and remake these every
time you run an interpreter that needs readline. It is probably
better to have the interpreters cache these, which in turn means
#endif
gdb_rl_callback_handler_remove ();
- delete_file_handler (input_fd);
+ delete_file_handler (ui->input_fd);
}
extern int async_command_editing_p;
extern int exec_done_display_p;
extern struct prompts the_prompts;
-extern int input_fd;
extern void (*after_char_processing_hook) (void);
extern int call_stdin_event_handler_again_p;
extern void gdb_readline_no_editing_callback (void *client_data);
if (!async_terminal_is_ours)
return;
- delete_file_handler (input_fd);
async_terminal_is_ours = 0;
set_sigint_trap ();
}
return;
clear_sigint_trap ();
- add_file_handler (input_fd, stdin_event_handler, 0);
async_terminal_is_ours = 1;
}
saved_command_line = (char *) xstrdup ("");
ui->instream = stdin;
+ ui->input_fd = fileno (stdin);
#ifdef __MINGW32__
/* Ensure stderr is unbuffered. A Cygwin pty or pipe is implemented
can go away. */
if (!remote_async_terminal_ours_p)
return;
- delete_file_handler (input_fd);
remote_async_terminal_ours_p = 0;
/* NOTE: At this point we could also register our selves as the
recipient of all input. Any characters typed could then be
/* See FIXME in remote_terminal_inferior. */
if (remote_async_terminal_ours_p)
return;
- add_file_handler (input_fd, stdin_event_handler, 0);
remote_async_terminal_ours_p = 1;
}
#include "agent.h"
#include "auxv.h"
#include "target-debug.h"
+#include "top.h"
+#include "event-top.h"
static void target_info (char *, int);
void
target_terminal_inferior (void)
{
+ struct ui *ui = current_ui;
+
/* A background resume (``run&'') should leave GDB in control of the
terminal. Use target_can_async_p, not target_is_async_p, since at
this point the target is not async yet. However, if sync_execution
if (target_can_async_p () && !sync_execution)
return;
+ /* Always delete the current UI's input file handler, regardless of
+ terminal_state, because terminal_state is only valid for the main
+ UI. */
+ delete_file_handler (ui->input_fd);
+
if (terminal_state == terminal_is_inferior)
return;
void
target_terminal_ours (void)
{
+ struct ui *ui = current_ui;
+
+ /* Always add the current UI's input file handler, regardless of
+ terminal_state, because terminal_state is only valid for the main
+ UI. */
+ add_file_handler (ui->input_fd, stdin_event_handler, ui);
+
if (terminal_state == terminal_is_ours)
return;
interacting via a GUI. */
FILE *instream;
+ /* The file descriptor for the input stream, so that we can register
+ it with the event loop. */
+ int input_fd;
+
/* The fields below that start with "m_" are "private". They're
meant to be accessed through wrapper macros that make them look
like globals. */