diff --git a/gdb/event-top.c b/gdb/event-top.c
index ddeaf80..c94b365 100644
--- a/gdb/event-top.c
+++ b/gdb/event-top.c
@@ -95,10 +95,6 @@ int async_command_editing_p;
    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.  */
@@ -412,12 +408,16 @@ get_line_builder (void)
 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);
     }
@@ -1040,18 +1040,11 @@ gdb_setup_readline (void)
   /* 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
@@ -1060,6 +1053,8 @@ gdb_setup_readline (void)
 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
@@ -1074,5 +1069,5 @@ gdb_disable_readline (void)
 #endif
 
   gdb_rl_callback_handler_remove ();
-  delete_file_handler (input_fd);
+  delete_file_handler (ui->input_fd);
 }
diff --git a/gdb/event-top.h b/gdb/event-top.h
index 4f89626..1b2cc59 100644
--- a/gdb/event-top.h
+++ b/gdb/event-top.h
@@ -57,7 +57,6 @@ extern void async_enable_stdin (void);
 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_callback_no_editing (void *client_data);
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index 6ded38d..614231a 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -4292,7 +4292,6 @@ linux_nat_terminal_inferior (struct target_ops *self)
   if (!async_terminal_is_ours)
     return;
 
-  delete_file_handler (input_fd);
   async_terminal_is_ours = 0;
   set_sigint_trap ();
 }
@@ -4318,7 +4317,6 @@ linux_nat_terminal_ours (struct target_ops *self)
     return;
 
   clear_sigint_trap ();
-  add_file_handler (input_fd, stdin_event_handler, 0);
   async_terminal_is_ours = 1;
 }
 
diff --git a/gdb/main.c b/gdb/main.c
index 89037cf..eee9a8b 100644
--- a/gdb/main.c
+++ b/gdb/main.c
@@ -507,6 +507,7 @@ captured_main (void *data)
   clear_quit_flag ();
   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
diff --git a/gdb/remote.c b/gdb/remote.c
index 8831b50..52f44e0 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -5948,7 +5948,6 @@ remote_terminal_inferior (struct target_ops *self)
      can go away.  */
   if (!remote_async_terminal_ours_p)
     return;
-  delete_file_handler (input_fd);
   remote_async_terminal_ours_p = 0;
   async_initialize_sigint_signal_handler ();
   /* NOTE: At this point we could also register our selves as the
@@ -5967,7 +5966,6 @@ remote_terminal_ours (struct target_ops *self)
   if (remote_async_terminal_ours_p)
     return;
   async_cleanup_sigint_signal_handler (NULL);
-  add_file_handler (input_fd, stdin_event_handler, 0);
   remote_async_terminal_ours_p = 1;
 }
 
diff --git a/gdb/target.c b/gdb/target.c
index ac66a3a..86e7074 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -43,6 +43,8 @@
 #include "agent.h"
 #include "auxv.h"
 #include "target-debug.h"
+#include "top.h"
+#include "event-top.h"
 
 static void target_info (char *, int);
 
@@ -477,6 +479,8 @@ target_terminal_is_ours (void)
 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
@@ -484,6 +488,8 @@ target_terminal_inferior (void)
   if (target_can_async_p () && !sync_execution)
     return;
 
+  delete_file_handler (ui->input_fd);
+
   if (terminal_state == terminal_is_inferior)
     return;
 
@@ -498,6 +504,10 @@ target_terminal_inferior (void)
 void
 target_terminal_ours (void)
 {
+  struct ui *ui = current_ui;
+
+  add_file_handler (ui->input_fd, stdin_event_handler, ui);
+
   if (terminal_state == terminal_is_ours)
     return;
 
diff --git a/gdb/top.h b/gdb/top.h
index 6937eb3..ef50489 100644
--- a/gdb/top.h
+++ b/gdb/top.h
@@ -73,6 +73,10 @@ struct ui
      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 serial object that wraps stdin.  */
   struct serial *stdin_serial;
 
