+ if (resumed != NULL)
+ {
+ /* Note that unlike pressing Ctrl-C on the controlling terminal,
+ here we only interrupt one process, not the whole process
+ group. This is because interrupting a process group (with
+ either Ctrl-C or with kill(3) with negative PID) sends a
+ SIGINT to each process in the process group, and we may not
+ be debugging all processes in the process group. */
+#ifndef _WIN32
+ kill (resumed->inf->pid, SIGINT);
+#endif
+ }
+}
+
+/* Pass a Ctrl-C to the inferior as-if a Ctrl-C was pressed while the
+ inferior was in the foreground. Implementation of
+ target_pass_ctrlc for child/native targets. */
+
+void
+child_pass_ctrlc (struct target_ops *self)
+{
+ gdb_assert (!target_terminal::is_ours ());
+
+#ifdef HAVE_TERMIOS_H
+ if (job_control)
+ {
+ pid_t term_pgrp = tcgetpgrp (0);
+
+ /* If there's any inferior sharing our terminal, pass the SIGINT
+ to the terminal's foreground process group. This acts just
+ like the user typed a ^C on the terminal while the inferior
+ was in the foreground. Note that using a negative process
+ number in kill() is a System V-ism. The proper BSD interface
+ is killpg(). However, all modern BSDs support the System V
+ interface too. */
+
+ if (term_pgrp != -1 && term_pgrp != our_terminal_info.process_group)
+ {
+ kill (-term_pgrp, SIGINT);
+ return;
+ }
+ }
+#endif
+
+ /* Otherwise, pass the Ctrl-C to the first inferior that was resumed
+ in the foreground. */
+ for (inferior *inf : all_inferiors ())
+ {
+ if (inf->terminal_state != target_terminal_state::is_ours)
+ {
+ gdb_assert (inf->pid != 0);
+
+#ifndef _WIN32
+ kill (inf->pid, SIGINT);
+#endif
+ 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;