+ return;
+ }
+ }
+
+ /* If no inferior was resumed in the foreground, then how did the
+ !is_ours assert above pass? */
+ gdb_assert_not_reached ("no inferior resumed in the fg found");
+}
+
+/* Per-inferior data key. */
+static const struct inferior_key<terminal_info> inflow_inferior_data;
+
+terminal_info::~terminal_info ()
+{
+ xfree (run_terminal);
+ xfree (ttystate);
+}
+
+/* Get the current svr4 data. If none is found yet, add it now. This
+ function always returns a valid object. */
+
+static struct terminal_info *
+get_inflow_inferior_data (struct inferior *inf)
+{
+ struct terminal_info *info;
+
+ info = inflow_inferior_data.get (inf);
+ if (info == NULL)
+ info = inflow_inferior_data.emplace (inf);
+
+ return info;
+}
+
+/* This is a "inferior_exit" observer. Releases the TERMINAL_INFO member
+ of the inferior structure. This field is private to inflow.c, and
+ its type is opaque to the rest of GDB. PID is the target pid of
+ the inferior that is about to be removed from the inferior
+ list. */
+
+static void
+inflow_inferior_exit (struct inferior *inf)
+{
+ inf->terminal_state = target_terminal_state::is_ours;
+ inflow_inferior_data.clear (inf);
+}
+
+void
+copy_terminal_info (struct inferior *to, struct inferior *from)
+{
+ struct terminal_info *tinfo_to, *tinfo_from;
+
+ tinfo_to = get_inflow_inferior_data (to);
+ tinfo_from = get_inflow_inferior_data (from);
+
+ xfree (tinfo_to->run_terminal);
+ xfree (tinfo_to->ttystate);
+
+ *tinfo_to = *tinfo_from;
+
+ if (tinfo_from->run_terminal)
+ tinfo_to->run_terminal
+ = xstrdup (tinfo_from->run_terminal);
+
+ if (tinfo_from->ttystate)
+ tinfo_to->ttystate
+ = serial_copy_tty_state (stdin_serial, tinfo_from->ttystate);
+
+ to->terminal_state = from->terminal_state;
+}
+
+/* See terminal.h. */
+
+void
+swap_terminal_info (inferior *a, inferior *b)
+{
+ terminal_info *info_a = inflow_inferior_data.get (a);
+ terminal_info *info_b = inflow_inferior_data.get (b);
+
+ inflow_inferior_data.set (a, info_b);
+ inflow_inferior_data.set (b, info_a);