/* Low level interface to ptrace, for GDB when running under Unix.
   Copyright (C) 1986-2021 Free Software Foundation, Inc.

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#include "defs.h"
#include "frame.h"
#include "inferior.h"
#include "command.h"
#include "serial.h"
#include "terminal.h"
#include "target.h"
#include "gdbthread.h"
#include "observable.h"
#include <signal.h>
#include <fcntl.h>
#include "gdbsupport/gdb_select.h"

#include "gdbcmd.h"
#ifdef HAVE_TERMIOS_H
#include <termios.h>
#endif
#include "gdbsupport/job-control.h"
#include "gdbsupport/scoped_ignore_sigttou.h"

#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif

#ifndef O_NOCTTY
#define O_NOCTTY 0
#endif

static void pass_signal (int);

static void child_terminal_ours_1 (target_terminal_state);

/* Record terminal status separately for debugger and inferior.  */

static struct serial *stdin_serial;

/* Terminal related info we need to keep track of.  Each inferior
   holds an instance of this structure --- we save it whenever the
   corresponding inferior stops, and restore it to the terminal when
   the inferior is resumed in the foreground.  */
struct terminal_info
{
  terminal_info () = default;
  ~terminal_info ();

  terminal_info &operator= (const terminal_info &) = default;

  /* The name of the tty (from the `tty' command) that we gave to the
     inferior when it was started.  */
  std::string run_terminal;

  /* TTY state.  We save it whenever the inferior stops, and restore
     it when it resumes in the foreground.  */
  serial_ttystate ttystate {};

#ifdef HAVE_TERMIOS_H
  /* The terminal's foreground process group.  Saved whenever the
     inferior stops.  This is the pgrp displayed by "info terminal".
     Note that this may be not the inferior's actual process group,
     since each inferior that we spawn has its own process group, and
     only one can be in the foreground at a time.  When the inferior
     resumes, if we can determine the inferior's actual pgrp, then we
     make that the foreground pgrp instead of what was saved here.
     While it's a bit arbitrary which inferior's pgrp ends up in the
     foreground when we resume several inferiors, this at least makes
     'resume inf1+inf2' + 'stop all' + 'resume inf2' end up with
     inf2's pgrp in the foreground instead of inf1's (which would be
     problematic since it would be left stopped: Ctrl-C wouldn't work,
     for example).  */
  pid_t process_group = 0;
#endif

  /* fcntl flags.  Saved and restored just like ttystate.  */
  int tflags = 0;
};

/* Our own tty state, which we restore every time we need to deal with
   the terminal.  This is set once, when GDB first starts, and then
   whenever we enter/leave TUI mode (gdb_save_tty_state).  The
   settings of flags which readline saves and restores are
   unimportant.  */
static struct terminal_info our_terminal_info;

/* Snapshot of the initial tty state taken during initialization of
   GDB, before readline/ncurses have had a chance to change it.  This
   is used as the initial tty state given to each new spawned
   inferior.  Unlike our_terminal_info, this is only ever set
   once.  */
static serial_ttystate initial_gdb_ttystate;

static struct terminal_info *get_inflow_inferior_data (struct inferior *);

/* While the inferior is running, we want SIGINT and SIGQUIT to go to the
   inferior only.  If we have job control, that takes care of it.  If not,
   we save our handlers in these two variables and set SIGINT and SIGQUIT
   to SIG_IGN.  */

static sighandler_t sigint_ours;
#ifdef SIGQUIT
static sighandler_t sigquit_ours;
#endif

/* The name of the tty (from the `tty' command) that we're giving to
   the inferior when starting it up.  This is only (and should only
   be) used as a transient global by new_tty_prefork,
   create_tty_session, new_tty and new_tty_postfork, all called from
   fork_inferior, while forking a new child.  */
static std::string inferior_thisrun_terminal;

/* Track who owns GDB's terminal (is it GDB or some inferior?).  While
   target_terminal::is_ours() etc. tracks the core's intention and is
   independent of the target backend, this tracks the actual state of
   GDB's own tty.  So for example,

     (target_terminal::is_inferior () && gdb_tty_state == terminal_is_ours)

   is true when the (native) inferior is not sharing a terminal with
   GDB (e.g., because we attached to an inferior that is running on a
   different terminal).  */
static target_terminal_state gdb_tty_state = target_terminal_state::is_ours;

/* See terminal.h.  */

void
set_initial_gdb_ttystate (void)
{
  /* Note we can't do any of this in _initialize_inflow because at
     that point stdin_serial has not been created yet.  */

  initial_gdb_ttystate = serial_get_tty_state (stdin_serial);

  if (initial_gdb_ttystate != NULL)
    {
      our_terminal_info.ttystate
	= serial_copy_tty_state (stdin_serial, initial_gdb_ttystate);
#ifdef F_GETFL
      our_terminal_info.tflags = fcntl (0, F_GETFL, 0);
#endif
#ifdef HAVE_TERMIOS_H
      our_terminal_info.process_group = tcgetpgrp (0);
#endif
    }
}

/* Does GDB have a terminal (on stdin)?  */

static int
gdb_has_a_terminal (void)
{
  return initial_gdb_ttystate != NULL;
}

/* Macro for printing errors from ioctl operations */

#define	OOPSY(what)	\
  if (result == -1)	\
    fprintf_unfiltered(gdb_stderr, "[%s failed in terminal_inferior: %s]\n", \
	    what, safe_strerror (errno))

/* Initialize the terminal settings we record for the inferior,
   before we actually run the inferior.  */

void
child_terminal_init (struct target_ops *self)
{
  if (!gdb_has_a_terminal ())
    return;

  inferior *inf = current_inferior ();
  terminal_info *tinfo = get_inflow_inferior_data (inf);

#ifdef HAVE_TERMIOS_H
  /* A child we spawn should be a process group leader (PGID==PID) at
     this point, though that may not be true if we're attaching to an
     existing process.  */
  tinfo->process_group = inf->pid;
#endif

  xfree (tinfo->ttystate);
  tinfo->ttystate = serial_copy_tty_state (stdin_serial, initial_gdb_ttystate);
}

/* Save the terminal settings again.  This is necessary for the TUI
   when it switches to TUI or non-TUI mode;  curses changes the terminal
   and gdb must be able to restore it correctly.  */

void
gdb_save_tty_state (void)
{
  if (gdb_has_a_terminal ())
    {
      xfree (our_terminal_info.ttystate);
      our_terminal_info.ttystate = serial_get_tty_state (stdin_serial);
    }
}

/* Try to determine whether TTY is GDB's input terminal.  Returns
   TRIBOOL_UNKNOWN if we can't tell.  */

static tribool
is_gdb_terminal (const char *tty)
{
  struct stat gdb_tty;
  struct stat other_tty;
  int res;

  res = stat (tty, &other_tty);
  if (res == -1)
    return TRIBOOL_UNKNOWN;

  res = fstat (STDIN_FILENO, &gdb_tty);
  if (res == -1)
    return TRIBOOL_UNKNOWN;

  return ((gdb_tty.st_dev == other_tty.st_dev
	   && gdb_tty.st_ino == other_tty.st_ino)
	  ? TRIBOOL_TRUE
	  : TRIBOOL_FALSE);
}

/* Helper for sharing_input_terminal.  Try to determine whether
   inferior INF is using the same TTY for input as GDB is.  Returns
   TRIBOOL_UNKNOWN if we can't tell.  */

static tribool
sharing_input_terminal_1 (inferior *inf)
{
  /* Using host-dependent code here is fine, because the
     child_terminal_foo functions are meant to be used by child/native
     targets.  */
#if defined (__linux__) || defined (__sun__)
  char buf[100];

  xsnprintf (buf, sizeof (buf), "/proc/%d/fd/0", inf->pid);
  return is_gdb_terminal (buf);
#else
  return TRIBOOL_UNKNOWN;
#endif
}

/* Return true if the inferior is using the same TTY for input as GDB
   is.  If this is true, then we save/restore terminal flags/state.

   This is necessary because if inf->attach_flag is set, we don't
   offhand know whether we are sharing a terminal with the inferior or
   not.  Attaching a process without a terminal is one case where we
   do not; attaching a process which we ran from the same shell as GDB
   via `&' is one case where we do.

   If we can't determine, we assume the TTY is being shared.  This
   works OK if you're only debugging one inferior.  However, if you're
   debugging more than one inferior, and e.g., one is spawned by GDB
   with "run" (sharing terminal with GDB), and another is attached to
   (and running on a different terminal, as is most common), then it
   matters, because we can only restore the terminal settings of one
   of the inferiors, and in that scenario, we want to restore the
   settings of the "run"'ed inferior.

   Note, this is not the same as determining whether GDB and the
   inferior are in the same session / connected to the same
   controlling tty.  An inferior (fork child) may call setsid,
   disconnecting itself from the ctty, while still leaving
   stdin/stdout/stderr associated with the original terminal.  If
   we're debugging that process, we should also save/restore terminal
   settings.  */

static bool
sharing_input_terminal (inferior *inf)
{
  terminal_info *tinfo = get_inflow_inferior_data (inf);

  tribool res = sharing_input_terminal_1 (inf);

  if (res == TRIBOOL_UNKNOWN)
    {
      /* As fallback, if we can't determine by stat'ing the inferior's
	 tty directly (because it's not supported on this host) and
	 the child was spawned, check whether run_terminal is our tty.
	 This isn't ideal, since this is checking the child's
	 controlling terminal, not the input terminal (which may have
	 been redirected), but is still better than nothing.  A false
	 positive ("set inferior-tty" points to our terminal, but I/O
	 was redirected) is much more likely than a false negative
	 ("set inferior-tty" points to some other terminal, and then
	 output was redirected to our terminal), and with a false
	 positive we just end up trying to save/restore terminal
	 settings when we didn't need to or we actually can't.  */
      if (!tinfo->run_terminal.empty ())
	res = is_gdb_terminal (tinfo->run_terminal.c_str ());

      /* If we still can't determine, assume yes.  */
      if (res == TRIBOOL_UNKNOWN)
	return true;
    }

  return res == TRIBOOL_TRUE;
}

/* Put the inferior's terminal settings into effect.  This is
   preparation for starting or resuming the inferior.  */

void
child_terminal_inferior (struct target_ops *self)
{
  /* If we resume more than one inferior in the foreground on GDB's
     terminal, then the first inferior's terminal settings "win".
     Note that every child process is put in its own process group, so
     the first process that ends up resumed ends up determining which
     process group the kernel forwards Ctrl-C/Ctrl-Z (SIGINT/SIGTTOU)
     to.  */
  if (gdb_tty_state == target_terminal_state::is_inferior)
    return;

  inferior *inf = current_inferior ();
  terminal_info *tinfo = get_inflow_inferior_data (inf);

  if (gdb_has_a_terminal ()
      && tinfo->ttystate != NULL
      && sharing_input_terminal (inf))
    {
      int result;

      /* Ignore SIGTTOU since it will happen when we try to set the
	 terminal's state (if gdb_tty_state is currently
	 ours_for_output).  */
      scoped_ignore_sigttou ignore_sigttou;

#ifdef F_GETFL
      result = fcntl (0, F_SETFL, tinfo->tflags);
      OOPSY ("fcntl F_SETFL");
#endif

      result = serial_set_tty_state (stdin_serial, tinfo->ttystate);
      OOPSY ("setting tty state");

      if (!job_control)
	{
	  sigint_ours = signal (SIGINT, SIG_IGN);
#ifdef SIGQUIT
	  sigquit_ours = signal (SIGQUIT, SIG_IGN);
#endif
	}

      if (job_control)
	{
#ifdef HAVE_TERMIOS_H
	  /* If we can't tell the inferior's actual process group,
	     then restore whatever was the foreground pgrp the last
	     time the inferior was running.  See also comments
	     describing terminal_state::process_group.  */
#ifdef HAVE_GETPGID
	  result = tcsetpgrp (0, getpgid (inf->pid));
#else
	  result = tcsetpgrp (0, tinfo->process_group);
#endif
	  if (result == -1)
	    {
#if 0
	      /* This fails if either GDB has no controlling terminal,
		 e.g., running under 'setsid(1)', or if the inferior
		 is not attached to GDB's controlling terminal.  E.g.,
		 if it called setsid to create a new session or used
		 the TIOCNOTTY ioctl, or simply if we've attached to a
		 process running on another terminal and we couldn't
		 tell whether it was sharing GDB's terminal (and so
		 assumed yes).  */
	      fprintf_unfiltered
		(gdb_stderr,
		 "[tcsetpgrp failed in child_terminal_inferior: %s]\n",
		 safe_strerror (errno));
#endif
	    }
#endif
	}

      gdb_tty_state = target_terminal_state::is_inferior;
    }
}

/* Put some of our terminal settings into effect,
   enough to get proper results from our output,
   but do not change into or out of RAW mode
   so that no input is discarded.

   After doing this, either terminal_ours or terminal_inferior
   should be called to get back to a normal state of affairs.

   N.B. The implementation is (currently) no different than
   child_terminal_ours.  See child_terminal_ours_1.  */

void
child_terminal_ours_for_output (struct target_ops *self)
{
  child_terminal_ours_1 (target_terminal_state::is_ours_for_output);
}

/* Put our terminal settings into effect.
   First record the inferior's terminal settings
   so they can be restored properly later.

   N.B. Targets that want to use this with async support must build that
   support on top of this (e.g., the caller still needs to add stdin to the
   event loop).  E.g., see linux_nat_terminal_ours.  */

void
child_terminal_ours (struct target_ops *self)
{
  child_terminal_ours_1 (target_terminal_state::is_ours);
}

/* Save the current terminal settings in the inferior's terminal_info
   cache.  */

void
child_terminal_save_inferior (struct target_ops *self)
{
  /* Avoid attempting all the ioctl's when running in batch.  */
  if (!gdb_has_a_terminal ())
    return;

  inferior *inf = current_inferior ();
  terminal_info *tinfo = get_inflow_inferior_data (inf);

  /* No need to save/restore if the inferior is not sharing GDB's
     tty.  */
  if (!sharing_input_terminal (inf))
    return;

  xfree (tinfo->ttystate);
  tinfo->ttystate = serial_get_tty_state (stdin_serial);

#ifdef HAVE_TERMIOS_H
  tinfo->process_group = tcgetpgrp (0);
#endif

#ifdef F_GETFL
  tinfo->tflags = fcntl (0, F_GETFL, 0);
#endif
}

/* Switch terminal state to DESIRED_STATE, either is_ours, or
   is_ours_for_output.  */

static void
child_terminal_ours_1 (target_terminal_state desired_state)
{
  gdb_assert (desired_state != target_terminal_state::is_inferior);

  /* Avoid attempting all the ioctl's when running in batch.  */
  if (!gdb_has_a_terminal ())
    return;

  if (gdb_tty_state != desired_state)
    {
      int result ATTRIBUTE_UNUSED;

      /* Ignore SIGTTOU since it will happen when we try to set the
	 terminal's pgrp.  */
      scoped_ignore_sigttou ignore_sigttou;

      /* Set tty state to our_ttystate.  */
      serial_set_tty_state (stdin_serial, our_terminal_info.ttystate);

      /* If we only want output, then leave the inferior's pgrp in the
	 foreground, so that Ctrl-C/Ctrl-Z reach the inferior
	 directly.  */
      if (job_control && desired_state == target_terminal_state::is_ours)
	{
#ifdef HAVE_TERMIOS_H
	  result = tcsetpgrp (0, our_terminal_info.process_group);
#if 0
	  /* This fails on Ultrix with EINVAL if you run the testsuite
	     in the background with nohup, and then log out.  GDB never
	     used to check for an error here, so perhaps there are other
	     such situations as well.  */
	  if (result == -1)
	    fprintf_unfiltered (gdb_stderr,
				"[tcsetpgrp failed in child_terminal_ours: %s]\n",
				safe_strerror (errno));
#endif
#endif /* termios */
	}

      if (!job_control && desired_state == target_terminal_state::is_ours)
	{
	  signal (SIGINT, sigint_ours);
#ifdef SIGQUIT
	  signal (SIGQUIT, sigquit_ours);
#endif
	}

#ifdef F_GETFL
      result = fcntl (0, F_SETFL, our_terminal_info.tflags);
#endif

      gdb_tty_state = desired_state;
    }
}

/* Interrupt the inferior.  Implementation of target_interrupt for
   child/native targets.  */

void
child_interrupt (struct target_ops *self)
{
  /* Interrupt the first inferior that has a resumed thread.  */
  thread_info *resumed = NULL;
  for (thread_info *thr : all_non_exited_threads ())
    {
      if (thr->executing ())
	{
	  resumed = thr;
	  break;
	}
      if (thr->has_pending_waitstatus ())
	resumed = thr;
    }

  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 (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->ttystate);

  *tinfo_to = *tinfo_from;

  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);

  std::swap (a->terminal_state, b->terminal_state);
}

static void
info_terminal_command (const char *arg, int from_tty)
{
  target_terminal::info (arg, from_tty);
}

void
child_terminal_info (struct target_ops *self, const char *args, int from_tty)
{
  struct inferior *inf;
  struct terminal_info *tinfo;

  if (!gdb_has_a_terminal ())
    {
      printf_filtered (_("This GDB does not control a terminal.\n"));
      return;
    }

  if (inferior_ptid == null_ptid)
    return;

  inf = current_inferior ();
  tinfo = get_inflow_inferior_data (inf);

  printf_filtered (_("Inferior's terminal status "
		     "(currently saved by GDB):\n"));

  /* First the fcntl flags.  */
  {
    int flags;

    flags = tinfo->tflags;

    printf_filtered ("File descriptor flags = ");

#ifndef O_ACCMODE
#define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR)
#endif
    /* (O_ACCMODE) parens are to avoid Ultrix header file bug.  */
    switch (flags & (O_ACCMODE))
      {
      case O_RDONLY:
	printf_filtered ("O_RDONLY");
	break;
      case O_WRONLY:
	printf_filtered ("O_WRONLY");
	break;
      case O_RDWR:
	printf_filtered ("O_RDWR");
	break;
      }
    flags &= ~(O_ACCMODE);

#ifdef O_NONBLOCK
    if (flags & O_NONBLOCK)
      printf_filtered (" | O_NONBLOCK");
    flags &= ~O_NONBLOCK;
#endif

#if defined (O_NDELAY)
    /* If O_NDELAY and O_NONBLOCK are defined to the same thing, we will
       print it as O_NONBLOCK, which is good cause that is what POSIX
       has, and the flag will already be cleared by the time we get here.  */
    if (flags & O_NDELAY)
      printf_filtered (" | O_NDELAY");
    flags &= ~O_NDELAY;
#endif

    if (flags & O_APPEND)
      printf_filtered (" | O_APPEND");
    flags &= ~O_APPEND;

#if defined (O_BINARY)
    if (flags & O_BINARY)
      printf_filtered (" | O_BINARY");
    flags &= ~O_BINARY;
#endif

    if (flags)
      printf_filtered (" | 0x%x", flags);
    printf_filtered ("\n");
  }

#ifdef HAVE_TERMIOS_H
  printf_filtered ("Process group = %d\n", (int) tinfo->process_group);
#endif

  serial_print_tty_state (stdin_serial, tinfo->ttystate, gdb_stdout);
}

/* NEW_TTY_PREFORK is called before forking a new child process,
   so we can record the state of ttys in the child to be formed.
   TTYNAME is empty if we are to share the terminal with gdb;
   otherwise it contains the name of the desired tty.

   NEW_TTY is called in new child processes under Unix, which will
   become debugger target processes.  This actually switches to
   the terminal specified in the NEW_TTY_PREFORK call.  */

void
new_tty_prefork (std::string ttyname)
{
  /* Save the name for later, for determining whether we and the child
     are sharing a tty.  */
  inferior_thisrun_terminal = std::move (ttyname);
}

#if !defined(__GO32__) && !defined(_WIN32)
/* If RESULT, assumed to be the return value from a system call, is
   negative, print the error message indicated by errno and exit.
   MSG should identify the operation that failed.  */
static void
check_syscall (const char *msg, int result)
{
  if (result < 0)
    {
      print_sys_errmsg (msg, errno);
      _exit (1);
    }
}
#endif

void
new_tty (void)
{
  if (inferior_thisrun_terminal.empty ())
    return;
#if !defined(__GO32__) && !defined(_WIN32)
  int tty;

#ifdef TIOCNOTTY
  /* Disconnect the child process from our controlling terminal.  On some
     systems (SVR4 for example), this may cause a SIGTTOU, so temporarily
     ignore SIGTTOU.  */
  tty = open ("/dev/tty", O_RDWR);
  if (tty >= 0)
    {
      scoped_ignore_sigttou ignore_sigttou;

      ioctl (tty, TIOCNOTTY, 0);
      close (tty);
    }
#endif

  /* Now open the specified new terminal.  */
  tty = open (inferior_thisrun_terminal.c_str (), O_RDWR | O_NOCTTY);
  check_syscall (inferior_thisrun_terminal.c_str (), tty);

  /* Avoid use of dup2; doesn't exist on all systems.  */
  if (tty != 0)
    {
      close (0);
      check_syscall ("dup'ing tty into fd 0", dup (tty));
    }
  if (tty != 1)
    {
      close (1);
      check_syscall ("dup'ing tty into fd 1", dup (tty));
    }
  if (tty != 2)
    {
      close (2);
      check_syscall ("dup'ing tty into fd 2", dup (tty));
    }

#ifdef TIOCSCTTY
  /* Make tty our new controlling terminal.  */
  if (ioctl (tty, TIOCSCTTY, 0) == -1)
    /* Mention GDB in warning because it will appear in the inferior's
       terminal instead of GDB's.  */
    warning (_("GDB: Failed to set controlling terminal: %s"),
	     safe_strerror (errno));
#endif

  if (tty > 2)
    close (tty);
#endif /* !go32 && !win32 */
}

/* NEW_TTY_POSTFORK is called after forking a new child process, and
   adding it to the inferior table, to store the TTYNAME being used by
   the child, or empty if it sharing the terminal with gdb.  */

void
new_tty_postfork (void)
{
  /* Save the name for later, for determining whether we and the child
     are sharing a tty.  */

  struct inferior *inf = current_inferior ();
  struct terminal_info *tinfo = get_inflow_inferior_data (inf);

  tinfo->run_terminal = std::move (inferior_thisrun_terminal);
  inferior_thisrun_terminal.clear ();
}


/* Call set_sigint_trap when you need to pass a signal on to an attached
   process when handling SIGINT.  */

static void
pass_signal (int signo)
{
#ifndef _WIN32
  kill (inferior_ptid.pid (), SIGINT);
#endif
}

static sighandler_t osig;
static int osig_set;

void
set_sigint_trap (void)
{
  struct inferior *inf = current_inferior ();
  struct terminal_info *tinfo = get_inflow_inferior_data (inf);

  if (inf->attach_flag || !tinfo->run_terminal.empty ())
    {
      osig = signal (SIGINT, pass_signal);
      osig_set = 1;
    }
  else
    osig_set = 0;
}

void
clear_sigint_trap (void)
{
  if (osig_set)
    {
      signal (SIGINT, osig);
      osig_set = 0;
    }
}


/* Create a new session if the inferior will run in a different tty.
   A session is UNIX's way of grouping processes that share a controlling
   terminal, so a new one is needed if the inferior terminal will be
   different from GDB's.

   Returns the session id of the new session, 0 if no session was created
   or -1 if an error occurred.  */
pid_t
create_tty_session (void)
{
#ifdef HAVE_SETSID
  pid_t ret;

  if (!job_control || inferior_thisrun_terminal.empty ())
    return 0;

  ret = setsid ();
  if (ret == -1)
    warning (_("Failed to create new terminal session: setsid: %s"),
	     safe_strerror (errno));

  return ret;
#else
  return 0;
#endif /* HAVE_SETSID */
}

/* Get all the current tty settings (including whether we have a
   tty at all!).  We can't do this in _initialize_inflow because
   serial_fdopen() won't work until the serial_ops_list is
   initialized, but we don't want to do it lazily either, so
   that we can guarantee stdin_serial is opened if there is
   a terminal.  */
void
initialize_stdin_serial (void)
{
  stdin_serial = serial_fdopen (0);
}

void _initialize_inflow ();
void
_initialize_inflow ()
{
  add_info ("terminal", info_terminal_command,
	    _("Print inferior's saved terminal status."));

  /* OK, figure out whether we have job control.  */
  have_job_control ();

  gdb::observers::inferior_exit.attach (inflow_inferior_exit, "inflow");
}
