Add target_ops argument to to_pid_to_exec_file
[deliverable/binutils-gdb.git] / gdb / inflow.c
index 6ca5bd8cc4a05d179fef87f3eb9ecb75cc739501..09623aba85ae882b9fd6f38dcb7338e182c59095 100644 (file)
@@ -1,7 +1,5 @@
 /* Low level interface to ptrace, for GDB when running under Unix.
-   Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995,
-   1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
-   2009 Free Software Foundation, Inc.
+   Copyright (C) 1986-2014 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #include "gdbthread.h"
 #include "observer.h"
 
-#include "gdb_string.h"
+#include <string.h>
 #include <signal.h>
 #include <fcntl.h>
 #include "gdb_select.h"
 
 #include "inflow.h"
+#include "gdbcmd.h"
 
 #ifdef HAVE_SYS_IOCTL_H
 #include <sys/ioctl.h>
 #define O_NOCTTY 0
 #endif
 
-#if defined (SIGIO) && defined (FASYNC) && defined (FD_SET) && defined (F_SETOWN)
-static void handle_sigio (int);
-#endif
-
 extern void _initialize_inflow (void);
 
 static void pass_signal (int);
 
-static void kill_command (char *, int);
-
 static void terminal_ours_1 (int);
 \f
 /* Record terminal status separately for debugger and inferior.  */
@@ -88,6 +81,8 @@ struct terminal_info
    unimportant.  */
 static struct terminal_info our_terminal_info;
 
+static struct terminal_info *get_inflow_inferior_data (struct inferior *);
+
 #ifdef PROCESS_GROUP_TYPE
 
 /* Return the process group of the current inferior.  */
@@ -95,7 +90,7 @@ static struct terminal_info our_terminal_info;
 PROCESS_GROUP_TYPE
 inferior_process_group (void)
 {
-  return current_inferior ()->terminal_info->process_group;
+  return get_inflow_inferior_data (current_inferior ())->process_group;
 }
 #endif
 
@@ -125,6 +120,7 @@ static PROCESS_GROUP_TYPE
 gdb_getpgrp (void)
 {
   int process_group = -1;
+
 #ifdef HAVE_TERMIOS
   process_group = tcgetpgrp (0);
 #endif
@@ -144,10 +140,31 @@ enum
   }
 gdb_has_a_terminal_flag = have_not_checked;
 
+/* The value of the "interactive-mode" setting.  */
+static enum auto_boolean interactive_mode = AUTO_BOOLEAN_AUTO;
+
+/* Implement the "show interactive-mode" option.  */
+
+static void
+show_interactive_mode (struct ui_file *file, int from_tty,
+                       struct cmd_list_element *c,
+                       const char *value)
+{
+  if (interactive_mode == AUTO_BOOLEAN_AUTO)
+    fprintf_filtered (file, "Debugger's interactive mode "
+                           "is %s (currently %s).\n",
+                      value, gdb_has_a_terminal () ? "on" : "off");
+  else
+    fprintf_filtered (file, "Debugger's interactive mode is %s.\n", value);
+}
+
 /* Does GDB have a terminal (on stdin)?  */
 int
 gdb_has_a_terminal (void)
 {
+  if (interactive_mode != AUTO_BOOLEAN_AUTO)
+    return interactive_mode == AUTO_BOOLEAN_TRUE;
+
   switch (gdb_has_a_terminal_flag)
     {
     case yes:
@@ -200,20 +217,22 @@ static void terminal_ours_1 (int);
 void
 terminal_init_inferior_with_pgrp (int pgrp)
 {
-  if (gdb_has_a_terminal ())
-    {
-      struct inferior *inf = current_inferior ();
-
-      /* We could just as well copy our_ttystate (if we felt like
-         adding a new function serial_copy_tty_state()).  */
-      xfree (inf->terminal_info->ttystate);
-      inf->terminal_info->ttystate
-       = serial_get_tty_state (stdin_serial);
+  struct inferior *inf = current_inferior ();
+  struct terminal_info *tinfo = get_inflow_inferior_data (inf);
 
 #ifdef PROCESS_GROUP_TYPE
-      inf->terminal_info->process_group = pgrp;
+  /* Store the process group even without a terminal as it is used not
+     only to reset the tty foreground process group, but also to
+     interrupt the inferior.  */
+  tinfo->process_group = pgrp;
 #endif
 
+  if (gdb_has_a_terminal ())
+    {
+      xfree (tinfo->ttystate);
+      tinfo->ttystate = serial_copy_tty_state (stdin_serial,
+                                              our_terminal_info.ttystate);
+
       /* Make sure that next time we call terminal_inferior (which will be
          before the program runs, as it needs to be), we install the new
          process group.  */
@@ -226,19 +245,17 @@ terminal_init_inferior_with_pgrp (int pgrp)
    and gdb must be able to restore it correctly.  */
 
 void
-terminal_save_ours (void)
+terminal_save_ours (struct target_ops *self)
 {
   if (gdb_has_a_terminal ())
     {
-      /* We could just as well copy our_ttystate (if we felt like adding
-         a new function serial_copy_tty_state).  */
       xfree (our_terminal_info.ttystate);
       our_terminal_info.ttystate = serial_get_tty_state (stdin_serial);
     }
 }
 
 void
-terminal_init_inferior (void)
+terminal_init_inferior (struct target_ops *self)
 {
 #ifdef PROCESS_GROUP_TYPE
   /* This is for Lynx, and should be cleaned up by having Lynx be a separate
@@ -247,7 +264,7 @@ terminal_init_inferior (void)
      (and the non-threaded child_terminal_init_inferior can just pass in
      inferior_ptid to the same routine).  */
   /* We assume INFERIOR_PID is also the child's process group.  */
-  terminal_init_inferior_with_pgrp (PIDGET (inferior_ptid));
+  terminal_init_inferior_with_pgrp (ptid_get_pid (inferior_ptid));
 #endif /* PROCESS_GROUP_TYPE */
 }
 
@@ -255,18 +272,20 @@ terminal_init_inferior (void)
    This is preparation for starting or resuming the inferior.  */
 
 void
-terminal_inferior (void)
+terminal_inferior (struct target_ops *self)
 {
   struct inferior *inf;
+  struct terminal_info *tinfo;
 
   if (!terminal_is_ours)
     return;
 
   inf = current_inferior ();
+  tinfo = get_inflow_inferior_data (inf);
 
   if (gdb_has_a_terminal ()
-      && inf->terminal_info->ttystate != NULL
-      && inf->terminal_info->run_terminal == NULL)
+      && tinfo->ttystate != NULL
+      && tinfo->run_terminal == NULL)
     {
       int result;
 
@@ -274,8 +293,8 @@ terminal_inferior (void)
       /* Is there a reason this is being done twice?  It happens both
          places we use F_SETFL, so I'm inclined to think perhaps there
          is some reason, however perverse.  Perhaps not though...  */
-      result = fcntl (0, F_SETFL, inf->terminal_info->tflags);
-      result = fcntl (0, F_SETFL, inf->terminal_info->tflags);
+      result = fcntl (0, F_SETFL, tinfo->tflags);
+      result = fcntl (0, F_SETFL, tinfo->tflags);
       OOPSY ("fcntl F_SETFL");
 #endif
 
@@ -283,7 +302,7 @@ terminal_inferior (void)
          terminal_ours, we will not change in our out of raw mode with
          this call, so we don't flush any input.  */
       result = serial_set_tty_state (stdin_serial,
-                                    inf->terminal_info->ttystate);
+                                    tinfo->ttystate);
       OOPSY ("setting tty state");
 
       if (!job_control)
@@ -309,13 +328,13 @@ terminal_inferior (void)
       if (job_control)
        {
 #ifdef HAVE_TERMIOS
-         result = tcsetpgrp (0, inf->terminal_info->process_group);
+         result = tcsetpgrp (0, tinfo->process_group);
          if (!inf->attach_flag)
            OOPSY ("tcsetpgrp");
 #endif
 
 #ifdef HAVE_SGTTY
-         result = ioctl (0, TIOCSPGRP, &inf->terminal_info->process_group);
+         result = ioctl (0, TIOCSPGRP, &tinfo->process_group);
          if (!inf->attach_flag)
            OOPSY ("TIOCSPGRP");
 #endif
@@ -334,7 +353,7 @@ terminal_inferior (void)
    should be called to get back to a normal state of affairs.  */
 
 void
-terminal_ours_for_output (void)
+terminal_ours_for_output (struct target_ops *self)
 {
   terminal_ours_1 (1);
 }
@@ -344,7 +363,7 @@ terminal_ours_for_output (void)
    so they can be restored properly later.  */
 
 void
-terminal_ours (void)
+terminal_ours (struct target_ops *self)
 {
   terminal_ours_1 (0);
 }
@@ -357,21 +376,24 @@ static void
 terminal_ours_1 (int output_only)
 {
   struct inferior *inf;
+  struct terminal_info *tinfo;
 
   if (terminal_is_ours)
     return;
 
+  terminal_is_ours = 1;
+
   /* Checking inferior->run_terminal is necessary so that
      if GDB is running in the background, it won't block trying
      to do the ioctl()'s below.  Checking gdb_has_a_terminal
      avoids attempting all the ioctl's when running in batch.  */
 
   inf = current_inferior ();
+  tinfo = get_inflow_inferior_data (inf);
 
-  if (inf->terminal_info->run_terminal != NULL || gdb_has_a_terminal () == 0)
+  if (tinfo->run_terminal != NULL || gdb_has_a_terminal () == 0)
     return;
 
-  if (!terminal_is_ours)
     {
 #ifdef SIGTTOU
       /* Ignore this signal since it will happen when we try to set the
@@ -380,22 +402,20 @@ terminal_ours_1 (int output_only)
 #endif
       int result;
 
-      terminal_is_ours = 1;
-
 #ifdef SIGTTOU
       if (job_control)
        osigttou = (void (*)()) signal (SIGTTOU, SIG_IGN);
 #endif
 
-      xfree (inf->terminal_info->ttystate);
-      inf->terminal_info->ttystate = serial_get_tty_state (stdin_serial);
+      xfree (tinfo->ttystate);
+      tinfo->ttystate = serial_get_tty_state (stdin_serial);
 
 #ifdef PROCESS_GROUP_TYPE
       if (!inf->attach_flag)
        /* If setpgrp failed in terminal_inferior, this would give us
           our process group instead of the inferior's.  See
           terminal_inferior for details.  */
-       inf->terminal_info->process_group = gdb_getpgrp ();
+       tinfo->process_group = gdb_getpgrp ();
 #endif
 
       /* Here we used to set ICANON in our ttystate, but I believe this
@@ -409,11 +429,11 @@ terminal_ours_1 (int output_only)
          mode, to avoid flushing input.  We need to do the same thing
          regardless of output_only, because we don't have separate
          terminal_is_ours and terminal_is_ours_for_output flags.  It's OK,
-         though, since readline will deal with raw mode when/if it needs to.
-       */
+         though, since readline will deal with raw mode when/if it needs
+         to.  */
 
       serial_noflush_set_tty_state (stdin_serial, our_terminal_info.ttystate,
-                                   inf->terminal_info->ttystate);
+                                   tinfo->ttystate);
 
       if (job_control)
        {
@@ -425,7 +445,8 @@ terminal_ours_1 (int output_only)
             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 terminal_ours: %s]\n",
+           fprintf_unfiltered (gdb_stderr,
+                               "[tcsetpgrp failed in terminal_ours: %s]\n",
                                safe_strerror (errno));
 #endif
 #endif /* termios */
@@ -449,7 +470,7 @@ terminal_ours_1 (int output_only)
        }
 
 #ifdef F_GETFL
-      inf->terminal_info->tflags = fcntl (0, F_GETFL, 0);
+      tinfo->tflags = fcntl (0, F_GETFL, 0);
 
       /* Is there a reason this is being done twice?  It happens both
          places we use F_SETFL, so I'm inclined to think perhaps there
@@ -460,18 +481,35 @@ terminal_ours_1 (int output_only)
     }
 }
 
-/* This is a "new_inferior" observer.  It's business is to allocate
-   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 has just been added to
-   the inferior list.  */
+/* Per-inferior data key.  */
+static const struct inferior_data *inflow_inferior_data;
 
 static void
-inflow_new_inferior (int pid)
+inflow_inferior_data_cleanup (struct inferior *inf, void *arg)
 {
-  struct inferior *inf = find_inferior_pid (pid);
+  struct terminal_info *info = arg;
 
-  inf->terminal_info = XZALLOC (struct terminal_info);
+  xfree (info->run_terminal);
+  xfree (info->ttystate);
+  xfree (info);
+}
+
+/* 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 = inferior_data (inf, inflow_inferior_data);
+  if (info == NULL)
+    {
+      info = XCNEW (struct terminal_info);
+      set_inferior_data (inf, inflow_inferior_data, info);
+    }
+
+  return info;
 }
 
 /* This is a "inferior_exit" observer.  Releases the TERMINAL_INFO member
@@ -481,21 +519,40 @@ inflow_new_inferior (int pid)
    list.  */
 
 static void
-inflow_inferior_exit (int pid)
+inflow_inferior_exit (struct inferior *inf)
 {
-  struct inferior *inf = find_inferior_pid (pid);
+  struct terminal_info *info;
 
-  xfree (inf->terminal_info->run_terminal);
-  xfree (inf->terminal_info);
-  inf->terminal_info = NULL;
+  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);
+    }
 }
 
 void
 copy_terminal_info (struct inferior *to, struct inferior *from)
 {
-  *to->terminal_info = *from->terminal_info;
-  if (from->terminal_info->run_terminal)
-    to->terminal_info->run_terminal = from->terminal_info->run_terminal;
+  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);
 }
 
 void
@@ -505,9 +562,10 @@ term_info (char *arg, int from_tty)
 }
 
 void
-child_terminal_info (char *args, int from_tty)
+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 ())
     {
@@ -519,21 +577,23 @@ child_terminal_info (char *args, int from_tty)
     return;
 
   inf = current_inferior ();
+  tinfo = get_inflow_inferior_data (inf);
 
-  printf_filtered (_("Inferior's terminal status (currently saved by GDB):\n"));
+  printf_filtered (_("Inferior's terminal status "
+                    "(currently saved by GDB):\n"));
 
   /* First the fcntl flags.  */
   {
     int flags;
 
-    flags = inf->terminal_info->tflags;
+    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 */
+    /* (O_ACCMODE) parens are to avoid Ultrix header file bug */
     switch (flags & (O_ACCMODE))
       {
       case O_RDONLY:
@@ -579,13 +639,10 @@ child_terminal_info (char *args, int from_tty)
   }
 
 #ifdef PROCESS_GROUP_TYPE
-  printf_filtered ("Process group = %d\n",
-                  (int) inf->terminal_info->process_group);
+  printf_filtered ("Process group = %d\n", (int) tinfo->process_group);
 #endif
 
-  serial_print_tty_state (stdin_serial,
-                         inf->terminal_info->ttystate,
-                         gdb_stdout);
+  serial_print_tty_state (stdin_serial, tinfo->ttystate, gdb_stdout);
 }
 \f
 /* NEW_TTY_PREFORK is called before forking a new child process,
@@ -605,7 +662,7 @@ new_tty_prefork (const char *ttyname)
   inferior_thisrun_terminal = 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.  */
@@ -618,6 +675,7 @@ check_syscall (const char *msg, int result)
       _exit (1);
     }
 }
+#endif
 
 void
 new_tty (void)
@@ -630,7 +688,7 @@ new_tty (void)
 #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. */
+     ignore SIGTTOU.  */
   tty = open ("/dev/tty", O_RDWR);
   if (tty > 0)
     {
@@ -669,7 +727,7 @@ new_tty (void)
   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",
+    warning (_("GDB: Failed to set controlling terminal: %s"),
             safe_strerror (errno));
 #endif
 
@@ -689,21 +747,25 @@ new_tty_postfork (void)
      are sharing a tty.  */
 
   if (inferior_thisrun_terminal)
-    current_inferior ()->terminal_info->run_terminal
-      = xstrdup (inferior_thisrun_terminal);
+    {
+      struct inferior *inf = current_inferior ();
+      struct terminal_info *tinfo = get_inflow_inferior_data (inf);
+
+      tinfo->run_terminal = xstrdup (inferior_thisrun_terminal);
+    }
 
   inferior_thisrun_terminal = NULL;
 }
 
 \f
 /* Call set_sigint_trap when you need to pass a signal on to an attached
-   process when handling SIGINT */
+   process when handling SIGINT */
 
 static void
 pass_signal (int signo)
 {
 #ifndef _WIN32
-  kill (PIDGET (inferior_ptid), SIGINT);
+  kill (ptid_get_pid (inferior_ptid), SIGINT);
 #endif
 }
 
@@ -714,7 +776,9 @@ void
 set_sigint_trap (void)
 {
   struct inferior *inf = current_inferior ();
-  if (inf->attach_flag || inf->terminal_info->run_terminal)
+  struct terminal_info *tinfo = get_inflow_inferior_data (inf);
+
+  if (inf->attach_flag || tinfo->run_terminal)
     {
       osig = (void (*)()) signal (SIGINT, pass_signal);
       osig_set = 1;
@@ -752,7 +816,7 @@ create_tty_session (void)
 
   ret = setsid ();
   if (ret == -1)
-    warning ("Failed to create new terminal session: setsid: %s",
+    warning (_("Failed to create new terminal session: setsid: %s"),
             safe_strerror (errno));
 
   return ret;
@@ -816,6 +880,20 @@ _initialize_inflow (void)
   add_info ("terminal", term_info,
            _("Print inferior's saved terminal status."));
 
+  add_setshow_auto_boolean_cmd ("interactive-mode", class_support,
+                                &interactive_mode, _("\
+Set whether GDB's standard input is a terminal."), _("\
+Show whether GDB's standard input is a terminal."), _("\
+If on, GDB assumes that standard input is a terminal.  In practice, it\n\
+means that GDB should wait for the user to answer queries associated to\n\
+commands entered at the command prompt.  If off, GDB assumes that standard\n\
+input is not a terminal, and uses the default answer to all queries.\n\
+If auto (the default), determine which mode to use based on the standard\n\
+input settings."),
+                        NULL,
+                        show_interactive_mode,
+                        &setlist, &showlist);
+
   terminal_is_ours = 1;
 
   /* OK, figure out whether we have job control.  If neither termios nor
@@ -830,7 +908,7 @@ _initialize_inflow (void)
 #ifdef _SC_JOB_CONTROL
   job_control = sysconf (_SC_JOB_CONTROL);
 #else
-  job_control = 0;             /* have to assume the worst */
+  job_control = 0;             /* Have to assume the worst.  */
 #endif /* _SC_JOB_CONTROL */
 #endif /* _POSIX_JOB_CONTROL */
 #endif /* HAVE_TERMIOS */
@@ -843,6 +921,8 @@ _initialize_inflow (void)
 #endif /* TIOCGPGRP */
 #endif /* sgtty */
 
-  observer_attach_new_inferior (inflow_new_inferior);
   observer_attach_inferior_exit (inflow_inferior_exit);
+
+  inflow_inferior_data
+    = register_inferior_data_with_cleanup (NULL, inflow_inferior_data_cleanup);
 }
This page took 0.032107 seconds and 4 git commands to generate.