/* Low level interface to ptrace, for GDB when running under Unix.
- Copyright (C) 1986-2018 Free Software Foundation, Inc.
+ Copyright (C) 1986-2020 Free Software Foundation, Inc.
This file is part of GDB.
#ifdef HAVE_TERMIOS_H
#include <termios.h>
#endif
-#include "job-control.h"
+#include "gdbsupport/job-control.h"
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
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. */
- char *run_terminal;
+ char *run_terminal = nullptr;
/* TTY state. We save it whenever the inferior stops, and restore
it when it resumes in the foreground. */
- serial_ttystate ttystate;
+ serial_ttystate ttystate {};
#ifdef HAVE_TERMIOS_H
/* The terminal's foreground process group. Saved whenever the
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;
+ pid_t process_group = 0;
#endif
/* fcntl flags. Saved and restored just like ttystate. */
- int tflags;
+ int tflags = 0;
};
/* Our own tty state, which we restore every time we need to deal with
static struct terminal_info *get_inflow_inferior_data (struct inferior *);
-/* RAII class used to ignore SIGTTOU in a scope. */
-
-class scoped_ignore_sigttou
-{
-public:
- scoped_ignore_sigttou ()
- {
-#ifdef SIGTTOU
- if (job_control)
- m_osigttou = signal (SIGTTOU, SIG_IGN);
-#endif
- }
-
- ~scoped_ignore_sigttou ()
- {
-#ifdef SIGTTOU
- if (job_control)
- signal (SIGTTOU, m_osigttou);
-#endif
- }
-
- DISABLE_COPY_AND_ASSIGN (scoped_ignore_sigttou);
-
-private:
-#ifdef SIGTTOU
- sighandler_t m_osigttou = NULL;
-#endif
-};
-
/* 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
child_interrupt (struct target_ops *self)
{
/* Interrupt the first inferior that has a resumed thread. */
- thread_info *thr;
thread_info *resumed = NULL;
- ALL_NON_EXITED_THREADS (thr)
+ for (thread_info *thr : all_non_exited_threads ())
{
if (thr->executing)
{
/* Otherwise, pass the Ctrl-C to the first inferior that was resumed
in the foreground. */
- inferior *inf;
- ALL_INFERIORS (inf)
+ for (inferior *inf : all_inferiors ())
{
if (inf->terminal_state != target_terminal_state::is_ours)
{
}
/* Per-inferior data key. */
-static const struct inferior_data *inflow_inferior_data;
+static const struct inferior_key<terminal_info> inflow_inferior_data;
-static void
-inflow_inferior_data_cleanup (struct inferior *inf, void *arg)
+terminal_info::~terminal_info ()
{
- struct terminal_info *info = (struct terminal_info *) arg;
-
- xfree (info->run_terminal);
- xfree (info->ttystate);
- xfree (info);
+ xfree (run_terminal);
+ xfree (ttystate);
}
/* Get the current svr4 data. If none is found yet, add it now. This
{
struct terminal_info *info;
- info = (struct terminal_info *) inferior_data (inf, inflow_inferior_data);
+ info = inflow_inferior_data.get (inf);
if (info == NULL)
- {
- info = XCNEW (struct terminal_info);
- set_inferior_data (inf, inflow_inferior_data, info);
- }
+ info = inflow_inferior_data.emplace (inf);
return info;
}
static void
inflow_inferior_exit (struct inferior *inf)
{
- struct terminal_info *info;
-
inf->terminal_state = target_terminal_state::is_ours;
-
- info = (struct terminal_info *) inferior_data (inf, inflow_inferior_data);
- if (info != NULL)
- {
- xfree (info->run_terminal);
- xfree (info->ttystate);
- xfree (info);
- set_inferior_data (inf, inflow_inferior_data, NULL);
- }
+ inflow_inferior_data.clear (inf);
}
void
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);
return;
}
- if (ptid_equal (inferior_ptid, null_ptid))
+ if (inferior_ptid == null_ptid)
return;
inf = current_inferior ();
void
new_tty (void)
{
- int tty;
-
if (inferior_thisrun_terminal == 0)
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
pass_signal (int signo)
{
#ifndef _WIN32
- kill (ptid_get_pid (inferior_ptid), SIGINT);
+ kill (inferior_ptid.pid (), SIGINT);
#endif
}
have_job_control ();
gdb::observers::inferior_exit.attach (inflow_inferior_exit);
-
- inflow_inferior_data
- = register_inferior_data_with_cleanup (NULL, inflow_inferior_data_cleanup);
}