/* Multi-process control for GDB, the GNU debugger.

   Copyright (C) 2008-2025 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 "exec.h"
#include "inferior.h"
#include "gdbsupport/common-inferior.h"
#include "target.h"
#include "command.h"
#include "completer.h"
#include "cli/cli-cmds.h"
#include "gdbthread.h"
#include "ui-out.h"
#include "observable.h"
#include "gdbcore.h"
#include "symfile.h"
#include "gdbsupport/environ.h"
#include "cli/cli-utils.h"
#include "arch-utils.h"
#include "target-descriptions.h"
#include "target-connection.h"
#include "gdbsupport/gdb_tilde_expand.h"
#include "progspace-and-thread.h"
#include "gdbsupport/buildargv.h"
#include "cli/cli-style.h"
#include "interps.h"

intrusive_list<inferior> inferior_list;
static int highest_inferior_num;

/* See inferior.h.  */
bool print_inferior_events = true;

/* The Current Inferior.  This is a strong reference.  I.e., whenever
   an inferior is the current inferior, its refcount is
   incremented.  */
static inferior_ref current_inferior_;

struct inferior*
current_inferior (void)
{
  return current_inferior_.get ();
}

void
set_current_inferior (struct inferior *inf)
{
  /* There's always an inferior.  */
  gdb_assert (inf != NULL);

  current_inferior_ = inferior_ref::new_reference (inf);
}

private_inferior::~private_inferior () = default;

inferior::~inferior ()
{
  /* Before the inferior is deleted, all target_ops should be popped from
     the target stack, this leaves just the dummy_target behind.  If this
     is not done, then any target left in the target stack will be left
     with an artificially high reference count.  As the dummy_target is
     still on the target stack then we are about to loose a reference to
     that target, leaving its reference count artificially high.  However,
     this is not critical as the dummy_target is a singleton.  */
  gdb_assert (m_target_stack.top ()->stratum () == dummy_stratum);

  m_continuations.clear ();
}

inferior::inferior (int pid_)
  : num (++highest_inferior_num),
    pid (pid_),
    environment (gdb_environ::from_host_environ ())
{
  m_target_stack.push (get_dummy_target ());
}

/* See inferior.h.  */

int
inferior::unpush_target (struct target_ops *t)
{
  /* If unpushing the process stratum target from the inferior while threads
     exist in the inferior, ensure that we don't leave any threads of the
     inferior in the target's "resumed with pending wait status" list.

     See also the comment in set_thread_exited.  */
  if (t->stratum () == process_stratum)
    {
      process_stratum_target *proc_target = as_process_stratum_target (t);

      for (thread_info &thread : this->non_exited_threads ())
	proc_target->maybe_remove_resumed_with_pending_wait_status (&thread);
    }

  return m_target_stack.unpush (t);
}

/* See inferior.h.  */

void
inferior::unpush_target_and_assert (struct target_ops *target)
{
  gdb_assert (current_inferior () == this);

  if (!unpush_target (target))
    internal_error ("pop_all_targets couldn't find target %s\n",
		    target->shortname ());
}

/* See inferior.h.  */

void
inferior::pop_all_targets_above (enum strata stratum)
{
  /* Unpushing a target might cause it to close.  Some targets currently
     rely on the current_inferior being set for their ::close method, so we
     temporarily switch inferior now.  */
  scoped_restore_current_pspace_and_thread restore_pspace_and_thread;
  switch_to_inferior_no_thread (this);

  while (top_target ()->stratum () > stratum)
    unpush_target_and_assert (top_target ());
}

/* See inferior.h.  */

void
inferior::pop_all_targets_at_and_above (enum strata stratum)
{
  /* Unpushing a target might cause it to close.  Some targets currently
     rely on the current_inferior being set for their ::close method, so we
     temporarily switch inferior now.  */
  scoped_restore_current_pspace_and_thread restore_pspace_and_thread;
  switch_to_inferior_no_thread (this);

  while (top_target ()->stratum () >= stratum)
    unpush_target_and_assert (top_target ());
}

void
inferior::set_tty (std::string terminal_name)
{
  m_terminal = std::move (terminal_name);
}

const std::string &
inferior::tty ()
{
  return m_terminal;
}

/* See inferior.h.  */

void
inferior::set_args (gdb::array_view<char * const> args,
		    bool escape_shell_char)
{
  set_args (construct_inferior_arguments (args, escape_shell_char));
}

void
inferior::set_arch (gdbarch *arch)
{
  gdb_assert (arch != nullptr);
  gdb_assert (gdbarch_initialized_p (arch));
  m_gdbarch = arch;

  process_stratum_target *proc_target = this->process_target ();
  if (proc_target != nullptr)
    registers_changed_ptid (proc_target, ptid_t (this->pid));
}

void
inferior::add_continuation (std::function<void ()> &&cont)
{
  m_continuations.emplace_front (std::move (cont));
}

void
inferior::do_all_continuations ()
{
  while (!m_continuations.empty ())
    {
      auto iter = m_continuations.begin ();
      (*iter) ();
      m_continuations.erase (iter);
    }
}

/* Notify interpreters and observers that inferior INF was added.  */

static void
notify_inferior_added (inferior *inf)
{
  interps_notify_inferior_added (inf);
  gdb::observers::inferior_added.notify (inf);
}

struct inferior *
add_inferior_silent (int pid)
{
  inferior *inf = new inferior (pid);

  inferior_list.push_back (*inf);

  notify_inferior_added (inf);

  if (pid != 0)
    inferior_appeared (inf, pid);

  return inf;
}

struct inferior *
add_inferior (int pid)
{
  struct inferior *inf = add_inferior_silent (pid);

  if (print_inferior_events)
    {
      if (pid != 0)
	gdb_printf (_("[New inferior %d (%s)]\n"),
		    inf->num,
		    target_pid_to_str (ptid_t (pid)).c_str ());
      else
	gdb_printf (_("[New inferior %d]\n"), inf->num);
    }

  return inf;
}

/* See inferior.h.  */

thread_info *
inferior::find_thread (ptid_t ptid)
{
  auto it = this->ptid_thread_map.find (ptid);
  if (it != this->ptid_thread_map.end ())
    return it->second;
  else
    return nullptr;
}

/* See inferior.h.  */

void
inferior::clear_thread_list ()
{
  thread_list.clear_and_dispose ([=] (thread_info *thr)
    {
      threads_debug_printf ("deleting thread %s",
			    thr->ptid.to_string ().c_str ());
      set_thread_exited (thr, {}, true /* silent */);
      if (thr->deletable ())
	delete thr;
    });
  ptid_thread_map.clear ();
}

/* Notify interpreters and observers that inferior INF was removed.  */

static void
notify_inferior_removed (inferior *inf)
{
  interps_notify_inferior_removed (inf);
  gdb::observers::inferior_removed.notify (inf);
}

void
delete_inferior (struct inferior *inf)
{
  inf->clear_thread_list ();

  auto it = inferior_list.iterator_to (*inf);
  inferior_list.erase (it);

  notify_inferior_removed (inf);

  /* Pop all targets now, this ensures that inferior::unpush is called
     correctly.  As pop_all_targets ends up making a temporary switch to
     inferior INF then we need to make this call before we delete the
     program space, which we do below.  */
  inf->pop_all_targets ();

  /* If this program space is rendered useless, remove it. */
  if (inf->pspace->empty ())
    delete inf->pspace;

  delete inf;
}

/* Notify interpreters and observers that inferior INF disappeared.  */

static void
notify_inferior_disappeared (inferior *inf)
{
  interps_notify_inferior_disappeared (inf);
  gdb::observers::inferior_exit.notify (inf);
}

/* See inferior.h.  */

void
exit_inferior (struct inferior *inf)
{
  inf->clear_thread_list ();

  notify_inferior_disappeared (inf);

  inf->pid = 0;
  inf->fake_pid_p = false;
  inf->priv = NULL;

  if (inf->vfork_parent != NULL)
    {
      inf->vfork_parent->vfork_child = NULL;
      inf->vfork_parent = NULL;
    }
  if (inf->vfork_child != NULL)
    {
      inf->vfork_child->vfork_parent = NULL;
      inf->vfork_child = NULL;
    }

  inf->pending_detach = false;
  /* Reset it.  */
  inf->control = inferior_control_state (NO_STOP_QUIETLY);

  /* Clear the register cache and the frame cache.  */
  registers_changed ();
  reinit_frame_cache ();
}

/* See inferior.h.  */

void
detach_inferior (inferior *inf)
{
  /* Save the pid, since exit_inferior will reset it.  */
  int pid = inf->pid;

  exit_inferior (inf);

  if (print_inferior_events)
    gdb_printf (_("[Inferior %d (%s) detached]\n"),
		inf->num,
		target_pid_to_str (ptid_t (pid)).c_str ());
}

/* Notify interpreters and observers that inferior INF appeared.  */

static void
notify_inferior_appeared (inferior *inf)
{
  interps_notify_inferior_appeared (inf);
  gdb::observers::inferior_appeared.notify (inf);
}

void
inferior_appeared (struct inferior *inf, int pid)
{
  /* If this is the first inferior with threads, reset the global
     thread id.  */
  delete_exited_threads ();
  if (!any_thread_p ())
    init_thread_list ();

  inf->pid = pid;
  inf->has_exit_code = false;
  inf->exit_code = 0;

  notify_inferior_appeared (inf);
}

struct inferior *
find_inferior_id (int num)
{
  for (inferior *inf : all_inferiors ())
    if (inf->num == num)
      return inf;

  return NULL;
}

struct inferior *
find_inferior_pid (process_stratum_target *targ, int pid)
{
  /* Looking for inferior pid == 0 is always wrong, and indicative of
     a bug somewhere else.  There may be more than one with pid == 0,
     for instance.  */
  gdb_assert (pid != 0);

  for (inferior *inf : all_inferiors (targ))
    if (inf->pid == pid)
      return inf;

  return NULL;
}

/* See inferior.h */

struct inferior *
find_inferior_ptid (process_stratum_target *targ, ptid_t ptid)
{
  return find_inferior_pid (targ, ptid.pid ());
}

/* See inferior.h.  */

struct inferior *
find_inferior_for_program_space (struct program_space *pspace)
{
  struct inferior *cur_inf = current_inferior ();

  if (cur_inf->pspace == pspace)
    return cur_inf;

  for (inferior *inf : all_inferiors ())
    if (inf->pspace == pspace)
      return inf;

  return NULL;
}

int
have_inferiors (void)
{
  for (inferior *inf ATTRIBUTE_UNUSED : all_non_exited_inferiors ())
    return 1;

  return 0;
}

/* Return the number of live inferiors.  We account for the case
   where an inferior might have a non-zero pid but no threads, as
   in the middle of a 'mourn' operation.  */

int
number_of_live_inferiors (process_stratum_target *proc_target)
{
  int num_inf = 0;

  for (inferior *inf : all_non_exited_inferiors (proc_target))
    if (inf->has_execution ())
      for (thread_info &tp ATTRIBUTE_UNUSED : inf->non_exited_threads ())
	{
	  /* Found a live thread in this inferior, go to the next
	     inferior.  */
	  ++num_inf;
	  break;
	}

  return num_inf;
}

/* Return true if there is at least one live inferior.  */

int
have_live_inferiors (void)
{
  return number_of_live_inferiors (NULL) > 0;
}

/* Prune away any unused inferiors, and then prune away no longer used
   program spaces.  */

void
prune_inferiors (void)
{
  for (inferior *inf : all_inferiors_safe ())
    {
      if (!inf->deletable ()
	  || !inf->removable
	  || inf->pid != 0)
	continue;

      delete_inferior (inf);
    }
}

/* Simply returns the count of inferiors.  */

int
number_of_inferiors (void)
{
  auto rng = all_inferiors ();
  return std::distance (rng.begin (), rng.end ());
}

/* Converts an inferior process id to a string.  Like
   target_pid_to_str, but special cases the null process.  */

static std::string
inferior_pid_to_str (int pid)
{
  if (pid != 0)
    return target_pid_to_str (ptid_t (pid));
  else
    return _("<null>");
}

/* See inferior.h.  */

void
print_selected_inferior (struct ui_out *uiout)
{
  struct inferior *inf = current_inferior ();
  const char *filename = inf->pspace->exec_filename ();

  if (filename == NULL)
    filename = _("<noexec>");

  uiout->message (_("[Switching to inferior %d [%s] (%s)]\n"),
		  inf->num, inferior_pid_to_str (inf->pid).c_str (), filename);
}

/* Helper for print_inferior.  Returns the 'connection-id' string for
   PROC_TARGET.  */

static std::string
uiout_field_connection (process_stratum_target *proc_target)
{
  if (proc_target == NULL)
    return {};
  else
    {
      std::string conn_str = make_target_connection_string (proc_target);
      return string_printf ("%d (%s)", proc_target->connection_number,
			    conn_str.c_str ());
    }
}

/* Prints the list of inferiors and their details on UIOUT.  This is a
   version of 'info_inferior_command' suitable for use from MI.

   If REQUESTED_INFERIORS is not NULL, it's a list of GDB ids of the
   inferiors that should be printed.  Otherwise, all inferiors are
   printed.  */

static void
print_inferior (struct ui_out *uiout, const char *requested_inferiors)
{
  int inf_count = 0;
  size_t connection_id_len = 20;

  /* Compute number of inferiors we will print.  */
  for (inferior *inf : all_inferiors ())
    {
      if (!number_is_in_list (requested_inferiors, inf->num))
	continue;

      std::string conn = uiout_field_connection (inf->process_target ());
      if (connection_id_len < conn.size ())
	connection_id_len = conn.size ();

      ++inf_count;
    }

  if (inf_count == 0)
    {
      uiout->message ("No inferiors.\n");
      return;
    }

  ui_out_emit_table table_emitter (uiout, 5, inf_count, "inferiors");
  uiout->table_header (1, ui_left, "current", "");
  uiout->table_header (4, ui_left, "number", "Num");
  uiout->table_header (17, ui_left, "target-id", "Description");
  uiout->table_header (connection_id_len, ui_left,
		       "connection-id", "Connection");
  uiout->table_header (17, ui_left, "exec", "Executable");

  uiout->table_body ();

  /* Restore the current thread after the loop because we switch the
     inferior in the loop.  */
  scoped_restore_current_pspace_and_thread restore_pspace_thread;
  inferior *current_inf = current_inferior ();
  for (inferior *inf : all_inferiors ())
    {
      if (!number_is_in_list (requested_inferiors, inf->num))
	continue;

      ui_out_emit_tuple tuple_emitter (uiout, NULL);

      if (inf == current_inf)
	uiout->field_string ("current", "*");
      else
	uiout->field_skip ("current");

      uiout->field_signed ("number", inf->num);

      /* Because target_pid_to_str uses the current inferior,
	 switch the inferior.  */
      switch_to_inferior_no_thread (inf);

      uiout->field_string ("target-id", inferior_pid_to_str (inf->pid));

      std::string conn = uiout_field_connection (inf->process_target ());
      uiout->field_string ("connection-id", conn);

      if (inf->pspace->exec_filename () != nullptr)
	uiout->field_string ("exec", inf->pspace->exec_filename (),
			     file_name_style.style ());
      else
	uiout->field_skip ("exec");

      /* Print extra info that isn't really fit to always present in
	 tabular form.  Currently we print the vfork parent/child
	 relationships, if any.  */
      if (inf->vfork_parent)
	{
	  uiout->text (_("\n\tis vfork child of inferior "));
	  uiout->field_signed ("vfork-parent", inf->vfork_parent->num);
	}
      if (inf->vfork_child)
	{
	  uiout->text (_("\n\tis vfork parent of inferior "));
	  uiout->field_signed ("vfork-child", inf->vfork_child->num);
	}
      if (get_inferior_core_bfd (inf) != nullptr)
	{
	  uiout->text (_("\n\tcore file "));
	  uiout->field_string ("core-file",
			       bfd_get_filename (get_inferior_core_bfd (inf)),
			       file_name_style.style ());
	}

      uiout->text ("\n");
    }
}

static void
detach_inferior_command (const char *args, int from_tty)
{
  if (!args || !*args)
    error (_("Requires argument (inferior id(s) to detach)"));

  scoped_restore_current_thread restore_thread;

  number_or_range_parser parser (args);
  while (!parser.finished ())
    {
      int num = parser.get_number ();

      inferior *inf = find_inferior_id (num);
      if (inf == NULL)
	{
	  warning (_("Inferior ID %d not known."), num);
	  continue;
	}

      if (inf->pid == 0)
	{
	  warning (_("Inferior ID %d is not running."), num);
	  continue;
	}

      thread_info *tp = any_thread_of_inferior (inf);
      if (tp == NULL)
	{
	  warning (_("Inferior ID %d has no threads."), num);
	  continue;
	}

      switch_to_thread (tp);

      detach_command (NULL, from_tty);
    }
}

static void
kill_inferior_command (const char *args, int from_tty)
{
  if (!args || !*args)
    error (_("Requires argument (inferior id(s) to kill)"));

  scoped_restore_current_thread restore_thread;

  number_or_range_parser parser (args);
  while (!parser.finished ())
    {
      int num = parser.get_number ();

      inferior *inf = find_inferior_id (num);
      if (inf == NULL)
	{
	  warning (_("Inferior ID %d not known."), num);
	  continue;
	}

      if (inf->pid == 0)
	{
	  warning (_("Inferior ID %d is not running."), num);
	  continue;
	}

      thread_info *tp = any_thread_of_inferior (inf);
      if (tp == NULL)
	{
	  warning (_("Inferior ID %d has no threads."), num);
	  continue;
	}

      switch_to_thread (tp);

      target_kill ();
    }
}

/* See inferior.h.  */

void
switch_to_inferior_no_thread (inferior *inf)
{
  set_current_inferior (inf);
  switch_to_no_thread ();
  set_current_program_space (inf->pspace);
}

/* See regcache.h.  */

std::optional<scoped_restore_current_thread>
maybe_switch_inferior (inferior *inf)
{
  std::optional<scoped_restore_current_thread> maybe_restore_thread;
  if (inf != current_inferior ())
    {
      maybe_restore_thread.emplace ();
      switch_to_inferior_no_thread (inf);
    }

  return maybe_restore_thread;
}

static void
inferior_command (const char *args, int from_tty)
{
  struct inferior *inf;
  int num;

  if (args == nullptr)
    {
      inf = current_inferior ();
      gdb_assert (inf != nullptr);
      const char *filename = inf->pspace->exec_filename ();

      if (filename == nullptr)
	filename = _("<noexec>");

      gdb_printf (_("[Current inferior is %d [%s] (%s)]\n"),
		  inf->num, inferior_pid_to_str (inf->pid).c_str (),
		  filename);
    }
  else
    {
      num = parse_and_eval_long (args);

      inf = find_inferior_id (num);
      if (inf == NULL)
	error (_("Inferior ID %d not known."), num);

      if (inf->pid != 0)
	{
	  if (inf != current_inferior ())
	    {
	      thread_info *tp = any_thread_of_inferior (inf);
	      if (tp == NULL)
		error (_("Inferior has no threads."));

	      switch_to_thread (tp);
	    }

	  notify_user_selected_context_changed
	    (USER_SELECTED_INFERIOR
	     | USER_SELECTED_THREAD
	     | USER_SELECTED_FRAME);
	}
      else
	{
	  switch_to_inferior_no_thread (inf);

	  notify_user_selected_context_changed
	    (USER_SELECTED_INFERIOR);
	}

      /* Switching current inferior may have made one of the inferiors
	 prunable, so prune it.  */
      prune_inferiors ();
    }
}

/* Print information about currently known inferiors.  */

static void
info_inferiors_command (const char *args, int from_tty)
{
  print_inferior (current_uiout, args);
}

/* remove-inferior ID */

static void
remove_inferior_command (const char *args, int from_tty)
{
  if (args == NULL || *args == '\0')
    error (_("Requires an argument (inferior id(s) to remove)"));

  number_or_range_parser parser (args);
  while (!parser.finished ())
    {
      int num = parser.get_number ();
      struct inferior *inf = find_inferior_id (num);

      if (inf == NULL)
	{
	  warning (_("Inferior ID %d not known."), num);
	  continue;
	}

      if (!inf->deletable ())
	{
	  warning (_("Can not remove current inferior %d."), num);
	  continue;
	}
    
      if (inf->pid != 0)
	{
	  warning (_("Can not remove active inferior %d."), num);
	  continue;
	}

      delete_inferior (inf);
    }
}

struct inferior *
add_inferior_with_spaces (void)
{
  struct program_space *pspace;
  struct inferior *inf;

  /* If all inferiors share an address space on this system, this
     doesn't really return a new address space; otherwise, it
     really does.  */
  pspace = new program_space (maybe_new_address_space ());
  inf = add_inferior (0);
  inf->pspace = pspace;
  inf->aspace = pspace->aspace;

  /* Setup the inferior's initial arch, based on information obtained
     from the global "set ..." options.  */
  gdbarch_info info;
  inf->set_arch (gdbarch_find_by_info (info));
  /* The "set ..." options reject invalid settings, so we should
     always have a valid arch by now.  */
  gdb_assert (inf->arch () != nullptr);

  return inf;
}

/* See inferior.h.  */

void
switch_to_inferior_and_push_target (inferior *new_inf,
				    bool no_connection, inferior *org_inf)
{
  process_stratum_target *proc_target = org_inf->process_target ();

  /* Switch over temporarily, while reading executable and
     symbols.  */
  switch_to_inferior_no_thread (new_inf);

  /* If the user didn't specify '-no-connection', and the ORG_INF has a
     process stratum target, but that target cannot be shared, or cannot
     start a new inferior, then don't try to share the target.  */
  if (!no_connection && proc_target != nullptr
      && (!proc_target->is_shareable ()
	  || !proc_target->can_create_inferior ()))
    {
      warning (_("can't share connection %d (%s) between inferiors"),
	       proc_target->connection_number,
	       make_target_connection_string (proc_target).c_str ());
      proc_target = nullptr;
    }

  /* Reuse the target for new inferior.  */
  if (!no_connection && proc_target != NULL)
    {
      new_inf->push_target (proc_target);
      gdb_printf (_("Added inferior %d on connection %d (%s)\n"),
		  new_inf->num,
		  proc_target->connection_number,
		  make_target_connection_string (proc_target).c_str ());
    }
  else
    gdb_printf (_("Added inferior %d\n"), new_inf->num);
}

/* Option values for the "add-inferior" command.  */

struct add_inferior_opts
{
  /* When true the new inferiors are started without a connection.  */
  bool no_connection = false;

  /* The number of new inferiors to add.  */
  unsigned int num_copies = 1;

  /* When non-empty, this is the executable for the new inferiors.  */
  std::string exec_filename;
};

/* Option definitions for the "add-inferior" command.  */

static const gdb::option::option_def add_inferior_option_defs[] = {
  gdb::option::uinteger_option_def<add_inferior_opts> {
    "copies",
    [] (add_inferior_opts *opts) { return &opts->num_copies; },
    (show_value_ftype *) nullptr, /* show_cmd_cb */
    N_("\
The number of inferiors to add.  The default is 1."),
  },

  gdb::option::filename_option_def<add_inferior_opts> {
    "exec",
    [] (add_inferior_opts *opts) { return &opts->exec_filename; },
    nullptr, /* show_cmd_cb */
    N_("\
FILENAME is the file name of the executable to use as the\n\
main program."),
  },

  gdb::option::flag_option_def<add_inferior_opts> {
    "no-connection",
    [] (add_inferior_opts *opts) { return &opts->no_connection; },
    N_("\
If specified, the new inferiors begin with no target connection.\n\
Without this flag the new inferiors inherit the current inferior's\n\
connection."),
  },
};

/* Create the option_def_group for the "add-inferior" command.  */

static inline gdb::option::option_def_group
make_add_inferior_options_def_group (add_inferior_opts *opts)
{
  return {{add_inferior_option_defs}, opts};
}

/* Completion for the "add-inferior" command.  */

static void
add_inferior_completer (struct cmd_list_element *cmd,
			completion_tracker &tracker,
			const char *text, const char * /* word */)
{
  /* The only completion offered is for the command options.  */
  const auto group = make_add_inferior_options_def_group (nullptr);
  gdb::option::complete_options
    (tracker, &text, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_ERROR, group);
}

/* add-inferior [-copies N] [-exec FILENAME] [-no-connection] */

static void
add_inferior_command (const char *args, int from_tty)
{
  add_inferior_opts opts;
  const auto group = make_add_inferior_options_def_group (&opts);
  gdb::option::process_options
    (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_ERROR, group);

  /* If an executable was given then perform tilde expansion.  */
  if (!opts.exec_filename.empty ())
    opts.exec_filename = gdb_tilde_expand (opts.exec_filename);

  symfile_add_flags add_flags = 0;
  if (from_tty)
    add_flags |= SYMFILE_VERBOSE;

  inferior *orginf = current_inferior ();

  scoped_restore_current_pspace_and_thread restore_pspace_thread;

  for (unsigned int i = 0; i < opts.num_copies; ++i)
    {
      inferior *inf = add_inferior_with_spaces ();

      switch_to_inferior_and_push_target (inf, opts.no_connection, orginf);

      if (!opts.exec_filename.empty ())
	{
	  const char *exec = opts.exec_filename.c_str ();
	  exec_file_attach (exec, from_tty);
	  symbol_file_add_main (exec, add_flags);
	}
    }
}

/* Option values for the "clone-inferior" command.  */

struct clone_inferior_opts
{
  /* When true the new inferiors are started without a connection.  */
  bool no_connection = false;

  /* The number of new inferiors to create by cloning.  */
  unsigned int num_copies = 1;
};


/* Option definitions for the "clone-inferior" command.  */

static const gdb::option::option_def clone_inferior_option_defs[] = {
  gdb::option::uinteger_option_def<clone_inferior_opts> {
    "copies",
    [] (clone_inferior_opts *opts) { return &opts->num_copies; },
    (show_value_ftype *) nullptr, /* show_cmd_cb */
    N_("\
The number of copies of inferior ID to create.  The default is 1."),
  },

  gdb::option::flag_option_def<clone_inferior_opts> {
    "no-connection",
    [] (clone_inferior_opts *opts) { return &opts->no_connection; },
    N_("\
If specified, the new inferiors begin with no target connection.\n\
Without this flag the new inferiors to inherit the copied inferior's\n\
connection."),
  },
};

/* Create the option_def_group for the "clone-inferior" command.  */

static inline gdb::option::option_def_group
make_clone_inferior_options_def_group (clone_inferior_opts *opts)
{
  return {{clone_inferior_option_defs}, opts};
}

/* Completion for the "clone-inferior" command.  */

static void
clone_inferior_completer (struct cmd_list_element *cmd,
			completion_tracker &tracker,
			const char *text, const char * /* word */)
{
  /* The only completion offered is for the command options.  */
  const auto group = make_clone_inferior_options_def_group (nullptr);
  gdb::option::complete_options
    (tracker, &text, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, group);
}

/* clone-inferior [-copies N] [-no-connection] [ID] */

static void
clone_inferior_command (const char *args, int from_tty)
{
  clone_inferior_opts opts;
  const auto group = make_clone_inferior_options_def_group (&opts);
  gdb::option::process_options
    (&args, gdb::option::PROCESS_OPTIONS_UNKNOWN_IS_OPERAND, group);

  struct inferior *orginf = NULL;
  if (args != nullptr && *args != '\0')
    {
      gdb_argv argv (args);

      gdb_assert (argv.count () > 0);

      for (const char *arg : argv)
	{
	  if (orginf == nullptr)
	    {
	      /* The first non-option argument specifies the number of the
		 inferior to clone.  */
	      int num = parse_and_eval_long (arg);
	      orginf = find_inferior_id (num);

	      if (orginf == nullptr)
		error (_("Inferior ID %d not known."), num);
	    }
	  else
	    error (_("Unexpected argument: %s."), arg);
	}
    }
  else
    {
      /* If no inferior id was specified, then the user wants to clone the
	 current inferior.  */
      orginf = current_inferior ();
    }

  gdb_assert (orginf != nullptr);

  scoped_restore_current_pspace_and_thread restore_pspace_thread;

  for (unsigned int i = 0; i < opts.num_copies; ++i)
    {
      struct program_space *pspace;
      struct inferior *inf;

      /* If all inferiors share an address space on this system, this
	 doesn't really return a new address space; otherwise, it
	 really does.  */
      pspace = new program_space (maybe_new_address_space ());
      inf = add_inferior (0);
      inf->pspace = pspace;
      inf->aspace = pspace->aspace;
      inf->set_arch (orginf->arch ());

      switch_to_inferior_and_push_target (inf, opts.no_connection, orginf);

      /* If the original inferior had a user specified target
	 description, make the clone use it too.  */
      if (inf->tdesc_info.from_user_p ())
	inf->tdesc_info = orginf->tdesc_info;

      clone_program_space (pspace, orginf->pspace);

      /* Copy properties from the original inferior to the new one.  */
      inf->set_args (orginf->args ());
      inf->set_cwd (orginf->cwd ());
      inf->set_tty (orginf->tty ());
      for (const std::string &set_var : orginf->environment.user_set_env ())
	{
	  /* set_var has the form NAME=value.  Split on the first '='.  */
	  const std::string::size_type pos = set_var.find ('=');
	  gdb_assert (pos != std::string::npos);
	  const std::string varname = set_var.substr (0, pos);
	  inf->environment.set
	    (varname.c_str (), orginf->environment.get (varname.c_str ()));
	}
      for (const std::string &unset_var
	   : orginf->environment.user_unset_env ())
	inf->environment.unset (unset_var.c_str ());

      gdb::observers::inferior_cloned.notify (orginf, inf);
    }
}

/* Print notices when new inferiors are created and die.  */
static void
show_print_inferior_events (struct ui_file *file, int from_tty,
			   struct cmd_list_element *c, const char *value)
{
  gdb_printf (file, _("Printing of inferior events is %s.\n"), value);
}

/* Return a new value for the selected inferior's id.  */

static struct value *
inferior_id_make_value (struct gdbarch *gdbarch, struct internalvar *var,
			void *ignore)
{
  struct inferior *inf = current_inferior ();

  return value_from_longest (builtin_type (gdbarch)->builtin_int, inf->num);
}

/* Implementation of `$_inferior' variable.  */

static const struct internalvar_funcs inferior_funcs =
{
  inferior_id_make_value,
  NULL,
};

/* See inferior.h.  */

void
initialize_inferiors ()
{
  struct cmd_list_element *c = NULL;

  /* There's always one inferior.  Note that this function isn't an
     automatic _initialize_foo function, since other _initialize_foo
     routines may need to install their per-inferior data keys.  We
     can only allocate an inferior when all those modules have done
     that.  Do this after initialize_progspace, due to the
     current_program_space reference.  */
  set_current_inferior (add_inferior_silent (0));
  current_inferior_->pspace = current_program_space;
  current_inferior_->aspace = current_program_space->aspace;
  /* The architecture will be initialized shortly, by
     initialize_current_architecture.  */

  add_info ("inferiors", info_inferiors_command,
	    _("Print a list of inferiors being managed.\n\
Usage: info inferiors [ID]...\n\
If IDs are specified, the list is limited to just those inferiors.\n\
By default all inferiors are displayed."));

  const auto add_inf_opts = make_add_inferior_options_def_group (nullptr);
  static std::string add_inferior_command_help
    = gdb::option::build_help (_("\
Add a new inferior.\n\
Usage: add-inferior [-copies NUMBER] [-exec FILENAME] [-no-connection]\n\
\n\
Options:\n\
%OPTIONS%"), add_inf_opts);
  c = add_com ("add-inferior", no_class, add_inferior_command,
	       add_inferior_command_help.c_str ());
  set_cmd_completer_handle_brkchars (c, add_inferior_completer);

  add_com ("remove-inferiors", no_class, remove_inferior_command, _("\
Remove inferior ID (or list of IDs).\n\
Usage: remove-inferiors ID..."));

  const auto clone_inf_opts = make_clone_inferior_options_def_group (nullptr);
  static std::string clone_inferior_command_help
    = gdb::option::build_help (_("\
Clone an existing inferior.\n\
Usage: clone-inferior [-copies NUMBER] [-no-connection] [ID]\n\
ID is the inferior number to clone, this can be found with the\n\
'info inferiors' command.  If no ID is specified, then the current\n\
inferior is cloned.\n\
\n\
Options:\n\
%OPTIONS%"), clone_inf_opts);
  c = add_com ("clone-inferior", no_class, clone_inferior_command,
	       clone_inferior_command_help.c_str ());
  set_cmd_completer_handle_brkchars (c, clone_inferior_completer);

  add_cmd ("inferiors", class_run, detach_inferior_command, _("\
Detach from inferior ID (or list of IDS).\n\
Usage; detach inferiors ID..."),
	   &detachlist);

  add_cmd ("inferiors", class_run, kill_inferior_command, _("\
Kill inferior ID (or list of IDs).\n\
Usage: kill inferiors ID..."),
	   &killlist);

  add_cmd ("inferior", class_run, inferior_command, _("\
Use this command to switch between inferiors.\n\
Usage: inferior ID\n\
The new inferior ID must be currently known."),
	   &cmdlist);

  add_setshow_boolean_cmd ("inferior-events", no_class,
	 &print_inferior_events, _("\
Set printing of inferior events (such as inferior start and exit)."), _("\
Show printing of inferior events (such as inferior start and exit)."), NULL,
	 NULL,
	 show_print_inferior_events,
	 &setprintlist, &showprintlist);

  create_internalvar_type_lazy ("_inferior", &inferior_funcs, NULL);
}
