* Rename remote-es1800.c to remote-es.c
[deliverable/binutils-gdb.git] / gdb / procfs.c
index 407c65fe90aae96b3c6ed9d9ce7e5e0943a394d3..2b1b66099bebdd9af65397fb6bf8f7313f25afc3 100644 (file)
@@ -1,5 +1,5 @@
 /* Machine independent support for SVR4 /proc (process file system) for GDB.
-   Copyright (C) 1991 Free Software Foundation, Inc.
+   Copyright 1991, 1992 Free Software Foundation, Inc.
    Written by Fred Fish at Cygnus Support.
 
 This file is part of GDB.
@@ -34,23 +34,25 @@ regardless of whether or not the actual target has floating point hardware.
 
 #include "defs.h"
 
-#ifdef USE_PROC_FS     /* Entire file goes away if not using /proc */
-
 #include <time.h>
 #include <sys/procfs.h>
 #include <fcntl.h>
 #include <errno.h>
+#include <string.h>
 
 #include "inferior.h"
 #include "target.h"
-#include "signame.h"
+#include "command.h"
+#include "gdbcore.h"
 
 #define MAX_SYSCALLS   256     /* Maximum number of syscalls for table */
 
 #ifndef PROC_NAME_FMT
-#define PROC_NAME_FMT "/proc/%d"
+#define PROC_NAME_FMT "/proc/%05d"
 #endif
 
+extern struct target_ops procfs_ops;           /* Forward declaration */
+
 #if 1  /* FIXME: Gross and ugly hack to resolve coredep.c global */
 CORE_ADDR kernel_u_addr;
 #endif
@@ -77,6 +79,7 @@ struct procinfo {
   int fd;                      /* File descriptor for /proc entry */
   char *pathname;              /* Pathname to /proc entry */
   int was_stopped;             /* Nonzero if was stopped prior to attach */
+  int nopass_next_sigstop;     /* Don't pass a sigstop on next resume */
   prrun_t prrun;               /* Control state when it is run */
   prstatus_t prstatus;         /* Current process status info */
   gregset_t gregset;           /* General register set */
@@ -136,6 +139,18 @@ static struct trans pr_flag_table[] =
 #endif
 #if defined (PR_ISSYS)
   PR_ISSYS, "PR_ISSYS", "Is a system process",
+#endif
+#if defined (PR_STEP)
+  PR_STEP, "PR_STEP", "Process has single step pending",
+#endif
+#if defined (PR_KLC)
+  PR_KLC, "PR_KLC", "Kill-on-last-close is in effect",
+#endif
+#if defined (PR_ASYNC)
+  PR_ASYNC, "PR_ASYNC", "Asynchronous stop is in effect",
+#endif
+#if defined (PR_PCOMPAT)
+  PR_PCOMPAT, "PR_PCOMPAT", "Ptrace compatibility mode in effect",
 #endif
  0, NULL, NULL
 };
@@ -161,6 +176,9 @@ static struct trans pr_why_table[] =
 #endif
 #if defined (PR_JOBCONTROL)
  PR_JOBCONTROL, "PR_JOBCONTROL", "Default job control stop signal action",
+#endif
+#if defined (PR_SUSPENDED)
+ PR_SUSPENDED, "PR_SUSPENDED", "Process suspended",
 #endif
  0, NULL, NULL
 };
@@ -322,380 +340,6 @@ static struct sigcode {
   0, 0, NULL, NULL
 };
 
-/* Translation table for errno values.  See intro(2) in most UNIX systems
-   Programmers Reference Manuals.
-
-   Note that some systems provide a function (strerror) that returns the
-   error message string, or a global variable that is the base address of the
-   array of character pointers.  Perhaps we should try to make use of these
-   provided strings if they are present, but at least this is more portable.
-   (FIXME?) */
-
-static struct trans errno_table[] =
-{
-#if defined (EPERM)
-  EPERM, "EPERM", "Not super-user",
-#endif
-#if defined (ENOENT)
-  ENOENT, "ENOENT", "No such file or directory",
-#endif
-#if defined (ESRCH)
-  ESRCH, "ESRCH", "No such process",
-#endif
-#if defined (EINTR)
-  EINTR, "EINTR", "Interrupted system call",
-#endif
-#if defined (EIO)
-  EIO, "EIO", "I/O error",
-#endif
-#if defined (ENXIO)
-  ENXIO, "ENXIO", "No such device or address",
-#endif
-#if defined (E2BIG)
-  E2BIG, "E2BIG", "Arg list too long",
-#endif
-#if defined (ENOEXEC)
-  ENOEXEC, "ENOEXEC", "Exec format error",
-#endif
-#if defined (EBADF)
-  EBADF, "EBADF", "Bad file number",
-#endif
-#if defined (ECHILD)
-  ECHILD, "ECHILD", "No child process",
-#endif
-#if defined (EAGAIN)
-  EAGAIN, "EAGAIN", "No more processes",
-#endif
-#if defined (ENOMEM)
-  ENOMEM, "ENOMEM", "Not enough space",
-#endif
-#if defined (EACCES)
-  EACCES, "EACCES", "Permission denied",
-#endif
-#if defined (EFAULT)
-  EFAULT, "EFAULT", "Bad address",
-#endif
-#if defined (ENOTBLK)
-  ENOTBLK, "ENOTBLK", "Block device required",
-#endif
-#if defined (EBUSY)
-  EBUSY, "EBUSY", "Device busy",
-#endif
-#if defined (EEXIST)
-  EEXIST, "EEXIST", "File exists",
-#endif
-#if defined (EXDEV)
-  EXDEV, "EXDEV", "Cross-device link",
-#endif
-#if defined (ENODEV)
-  ENODEV, "ENODEV", "No such device",
-#endif
-#if defined (ENOTDIR)
-  ENOTDIR, "ENOTDIR", "Not a directory",
-#endif
-#if defined (EISDIR)
-  EISDIR, "EISDIR", "Is a directory",
-#endif
-#if defined (EINVAL)
-  EINVAL, "EINVAL", "Invalid argument",
-#endif
-#if defined (ENFILE)
-  ENFILE, "ENFILE", "File table overflow",
-#endif
-#if defined (EMFILE)
-  EMFILE, "EMFILE", "Too many open files",
-#endif
-#if defined (ENOTTY)
-  ENOTTY, "ENOTTY", "Not a typewriter",
-#endif
-#if defined (ETXTBSY)
-  ETXTBSY, "ETXTBSY", "Text file busy",
-#endif
-#if defined (EFBIG)
-  EFBIG, "EFBIG", "File too large",
-#endif
-#if defined (ENOSPC)
-  ENOSPC, "ENOSPC", "No space left on device",
-#endif
-#if defined (ESPIPE)
-  ESPIPE, "ESPIPE", "Illegal seek",
-#endif
-#if defined (EROFS)
-  EROFS, "EROFS", "Read only file system",
-#endif
-#if defined (EMLINK)
-  EMLINK, "EMLINK", "Too many links",
-#endif
-#if defined (EPIPE)
-  EPIPE, "EPIPE", "Broken pipe",
-#endif
-#if defined (EDOM)
-  EDOM, "EDOM", "Math argument out of domain of func",
-#endif
-#if defined (ERANGE)
-  ERANGE, "ERANGE", "Math result not representable",
-#endif
-#if defined (ENOMSG)
-  ENOMSG, "ENOMSG", "No message of desired type",
-#endif
-#if defined (EIDRM)
-  EIDRM, "EIDRM", "Identifier removed",
-#endif
-#if defined (ECHRNG)
-  ECHRNG, "ECHRNG", "Channel number out of range",
-#endif
-#if defined (EL2NSYNC)
-  EL2NSYNC, "EL2NSYNC", "Level 2 not synchronized",
-#endif
-#if defined (EL3HLT)
-  EL3HLT, "EL3HLT", "Level 3 halted",
-#endif
-#if defined (EL3RST)
-  EL3RST, "EL3RST", "Level 3 reset",
-#endif
-#if defined (ELNRNG)
-  ELNRNG, "ELNRNG", "Link number out of range",
-#endif
-#if defined (EUNATCH)
-  EUNATCH, "EUNATCH", "Protocol driver not attached",
-#endif
-#if defined (ENOCSI)
-  ENOCSI, "ENOCSI", "No CSI structure available",
-#endif
-#if defined (EL2HLT)
-  EL2HLT, "EL2HLT", "Level 2 halted",
-#endif
-#if defined (EDEADLK)
-  EDEADLK, "EDEADLK", "Deadlock condition",
-#endif
-#if defined (ENOLCK)
-  ENOLCK, "ENOLCK", "No record locks available",
-#endif
-#if defined (EBADE)
-  EBADE, "EBADE", "Invalid exchange",
-#endif
-#if defined (EBADR)
-  EBADR, "EBADR", "Invalid request descriptor",
-#endif
-#if defined (EXFULL)
-  EXFULL, "EXFULL", "Exchange full",
-#endif
-#if defined (ENOANO)
-  ENOANO, "ENOANO", "No anode",
-#endif
-#if defined (EBADRQC)
-  EBADRQC, "EBADRQC", "Invalid request code",
-#endif
-#if defined (EBADSLT)
-  EBADSLT, "EBADSLT", "Invalid slot",
-#endif
-#if defined (EDEADLOCK)
-  EDEADLOCK, "EDEADLOCK", "File locking deadlock error",
-#endif
-#if defined (EBFONT)
-  EBFONT, "EBFONT", "Bad font file fmt",
-#endif
-#if defined (ENOSTR)
-  ENOSTR, "ENOSTR", "Device not a stream",
-#endif
-#if defined (ENODATA)
-  ENODATA, "ENODATA", "No data available",
-#endif
-#if defined (ETIME)
-  ETIME, "ETIME", "Timer expired",
-#endif
-#if defined (ENOSR)
-  ENOSR, "ENOSR", "Out of streams resources",
-#endif
-#if defined (ENONET)
-  ENONET, "ENONET", "Machine is not on the network",
-#endif
-#if defined (ENOPKG)
-  ENOPKG, "ENOPKG", "Package not installed",
-#endif
-#if defined (EREMOTE)
-  EREMOTE, "EREMOTE", "Object is remote",
-#endif
-#if defined (ENOLINK)
-  ENOLINK, "ENOLINK", "Link has been severed",
-#endif
-#if defined (EADV)
-  EADV, "EADV", "Advertise error",
-#endif
-#if defined (ESRMNT)
-  ESRMNT, "ESRMNT", "Srmount error",
-#endif
-#if defined (ECOMM)
-  ECOMM, "ECOMM", "Communication error on send",
-#endif
-#if defined (EPROTO)
-  EPROTO, "EPROTO", "Protocol error",
-#endif
-#if defined (EMULTIHOP)
-  EMULTIHOP, "EMULTIHOP", "Multihop attempted",
-#endif
-#if defined (EDOTDOT)
-  EDOTDOT, "EDOTDOT", "RFS specific error",
-#endif
-#if defined (EBADMSG)
-  EBADMSG, "EBADMSG", "Not a data message",
-#endif
-#if defined (ENAMETOOLONG)
-  ENAMETOOLONG, "ENAMETOOLONG", "File name too long",
-#endif
-#if defined (EOVERFLOW)
-  EOVERFLOW, "EOVERFLOW", "Value too large for defined data type",
-#endif
-#if defined (ENOTUNIQ)
-  ENOTUNIQ, "ENOTUNIQ", "Name not unique on network",
-#endif
-#if defined (EBADFD)
-  EBADFD, "EBADFD", "File descriptor in bad state",
-#endif
-#if defined (EREMCHG)
-  EREMCHG, "EREMCHG", "Remote address changed",
-#endif
-#if defined (ELIBACC)
-  ELIBACC, "ELIBACC", "Cannot access a needed shared library",
-#endif
-#if defined (ELIBBAD)
-  ELIBBAD, "ELIBBAD", "Accessing a corrupted shared library",
-#endif
-#if defined (ELIBSCN)
-  ELIBSCN, "ELIBSCN", ".lib section in a.out corrupted",
-#endif
-#if defined (ELIBMAX)
-  ELIBMAX, "ELIBMAX", "Attempting to link in too many shared libraries",
-#endif
-#if defined (ELIBEXEC)
-  ELIBEXEC, "ELIBEXEC", "Cannot exec a shared library directly",
-#endif
-#if defined (EILSEQ)
-  EILSEQ, "EILSEQ", "Illegal byte sequence",
-#endif
-#if defined (ENOSYS)
-  ENOSYS, "ENOSYS", "Operation not applicable",
-#endif
-#if defined (ELOOP)
-  ELOOP, "ELOOP", "Too many symbolic links encountered",
-#endif
-#if defined (ERESTART)
-  ERESTART, "ERESTART", "Interrupted system call should be restarted",
-#endif
-#if defined (ESTRPIPE)
-  ESTRPIPE, "ESTRPIPE", "Streams pipe error",
-#endif
-#if defined (ENOTEMPTY)
-  ENOTEMPTY, "ENOTEMPTY", "Directory not empty",
-#endif
-#if defined (EUSERS)
-  EUSERS, "EUSERS", "Too many users",
-#endif
-#if defined (ENOTSOCK)
-  ENOTSOCK, "ENOTSOCK", "Socket operation on non-socket",
-#endif
-#if defined (EDESTADDRREQ)
-  EDESTADDRREQ, "EDESTADDRREQ", "Destination address required",
-#endif
-#if defined (EMSGSIZE)
-  EMSGSIZE, "EMSGSIZE", "Message too long",
-#endif
-#if defined (EPROTOTYPE)
-  EPROTOTYPE, "EPROTOTYPE", "Protocol wrong type for socket",
-#endif
-#if defined (ENOPROTOOPT)
-  ENOPROTOOPT, "ENOPROTOOPT", "Protocol not available",
-#endif
-#if defined (EPROTONOSUPPORT)
-  EPROTONOSUPPORT, "EPROTONOSUPPORT", "Protocol not supported",
-#endif
-#if defined (ESOCKTNOSUPPORT)
-  ESOCKTNOSUPPORT, "ESOCKTNOSUPPORT", "Socket type not supported",
-#endif
-#if defined (EOPNOTSUPP)
-  EOPNOTSUPP, "EOPNOTSUPP", "Operation not supported on transport endpoint ",
-#endif
-#if defined (EPFNOSUPPORT)
-  EPFNOSUPPORT, "EPFNOSUPPORT", "Protocol family not supported",
-#endif
-#if defined (EAFNOSUPPORT)
-  EAFNOSUPPORT, "EAFNOSUPPORT", "Address family not supported by protocol",
-#endif
-#if defined (EADDRINUSE)
-  EADDRINUSE, "EADDRINUSE", "Address already in use",
-#endif
-#if defined (EADDRNOTAVAIL)
-  EADDRNOTAVAIL, "EADDRNOTAVAIL","Cannot assign requested address",
-#endif
-#if defined (ENETDOWN)
-  ENETDOWN, "ENETDOWN", "Network is down",
-#endif
-#if defined (ENETUNREACH)
-  ENETUNREACH, "ENETUNREACH", "Network is unreachable",
-#endif
-#if defined (ENETRESET)
-  ENETRESET, "ENETRESET", "Network dropped connection because of reset",
-#endif
-#if defined (ECONNABORTED)
-  ECONNABORTED, "ECONNABORTED", "Software caused connection abort",
-#endif
-#if defined (ECONNRESET)
-  ECONNRESET, "ECONNRESET", "Connection reset by peer",
-#endif
-#if defined (ENOBUFS)
-  ENOBUFS, "ENOBUFS", "No buffer space available",
-#endif
-#if defined (EISCONN)
-  EISCONN, "EISCONN", "Transport endpoint is already connected",
-#endif
-#if defined (ENOTCONN)
-  ENOTCONN, "ENOTCONN", "Transport endpoint is not connected",
-#endif
-#if defined (ESHUTDOWN)
-  ESHUTDOWN, "ESHUTDOWN", "Cannot send after transport endpoint shutdown",
-#endif
-#if defined (ETOOMANYREFS)
-  ETOOMANYREFS, "ETOOMANYREFS", "Too many references: cannot splice",
-#endif
-#if defined (ETIMEDOUT)
-  ETIMEDOUT, "ETIMEDOUT", "Connection timed out",
-#endif
-#if defined (ECONNREFUSED)
-  ECONNREFUSED, "ECONNREFUSED", "Connection refused",
-#endif
-#if defined (EHOSTDOWN)
-  EHOSTDOWN, "EHOSTDOWN", "Host is down",
-#endif
-#if defined (EHOSTUNREACH)
-  EHOSTUNREACH, "EHOSTUNREACH", "No route to host",
-#endif
-#if defined (EWOULDBLOCK)
-  EWOULDBLOCK, "EWOULDBLOCK", "Operation already in progress",
-#endif
-#if defined (EINPROGRESS)
-  EINPROGRESS, "EINPROGRESS", "Operation now in progress",
-#endif
-#if defined (ESTALE)
-  ESTALE, "ESTALE", "Stale NFS file handle",
-#endif
-#if defined (EUCLEAN)
-  EUCLEAN, "EUCLEAN", "Structure needs cleaning",
-#endif
-#if defined (ENOTNAM)
-  ENOTNAM, "ENOTNAM", "Not a XENIX named type file",
-#endif
-#if defined (ENAVAIL)
-  ENAVAIL, "ENAVAIL", "No XENIX semaphores available",
-#endif
-#if defined (EISNAM)
-  EISNAM, "EISNAM", "Is a named type file",
-#endif
-#if defined (EREMOTEIO)
-  EREMOTEIO, "EREMOTEIO", "Remote I/O error",
-#endif
- 0, NULL, NULL
-};
-
 static char *syscall_table[MAX_SYSCALLS];
 
 /* Prototypes for local functions */
@@ -712,11 +356,14 @@ syscallname PARAMS ((int));
 static char *
 signalname PARAMS ((int));
 
+static char *
+errnoname PARAMS ((int));
+
 static int
 proc_address_to_fd PARAMS ((CORE_ADDR, int));
 
 static int
-open_proc_file PARAMS ((int, struct procinfo *));
+open_proc_file PARAMS ((int, struct procinfo *, int));
 
 static void
 close_proc_file PARAMS ((struct procinfo *));
@@ -760,6 +407,18 @@ lookupname PARAMS ((struct trans *, unsigned int, char *));
 static char *
 lookupdesc PARAMS ((struct trans *, unsigned int));
 
+static int
+do_attach PARAMS ((int pid));
+
+static void
+do_detach PARAMS ((int siggnal));
+
+static void
+procfs_create_inferior PARAMS ((char *, char *, char **));
+
+static void
+procfs_notice_signals PARAMS ((void));
+
 /* External function prototypes that can't be easily included in any
    header file because the args are typedefs in system include files. */
 
@@ -868,7 +527,7 @@ lookupname (transp, val, prefix)
          free (locbuf);
        }
       locbuf = xmalloc (strlen (prefix) + 16);
-      (void) sprintf (locbuf, "%s %u", prefix, val);
+      sprintf (locbuf, "%s %u", prefix, val);
       name = locbuf;
     }
   return (name);
@@ -893,13 +552,14 @@ sigcodename (sip)
     }
   if (name == NULL)
     {
-      (void) sprintf (locbuf, "sigcode %u", sip -> si_signo);
+      sprintf (locbuf, "sigcode %u", sip -> si_signo);
       name = locbuf;
     }
   return (name);
 }
 
-static char *sigcodedesc (sip)
+static char *
+sigcodedesc (sip)
      siginfo_t *sip;
 {
   struct sigcode *scp;
@@ -951,7 +611,7 @@ syscallname (syscallnum)
     }
   else
     {
-      (void) sprintf (locbuf, "syscall %u", syscallnum);
+      sprintf (locbuf, "syscall %u", syscallnum);
       rtnval = locbuf;
     }
   return (rtnval);
@@ -982,8 +642,6 @@ NOTES
 static void
 init_syscall_table ()
 {
-  int syscallnum;
-  
 #if defined (SYS_exit)
   syscall_table[SYS_exit] = "exit";
 #endif
@@ -1363,7 +1021,7 @@ GLOBAL FUNCTION
 
 SYNOPSIS
 
-       int ptrace (int request, int pid, int arg3, int arg4)
+       int ptrace (int request, int pid, PTRACE_ARG3_TYPE arg3, int arg4)
 
 DESCRIPTION
 
@@ -1378,7 +1036,7 @@ int
 ptrace (request, pid, arg3, arg4)
      int request;
      int pid;
-     int arg3;
+     PTRACE_ARG3_TYPE arg3;
      int arg4;
 {
   error ("internal error - there is a call to ptrace() somewhere");
@@ -1387,46 +1045,13 @@ ptrace (request, pid, arg3, arg4)
 
 /*
 
-GLOBAL FUNCTION
-
-       kill_inferior_fast -- kill inferior while gdb is exiting
-
-SYNOPSIS
-
-       void kill_inferior_fast (void)
-
-DESCRIPTION
-
-       This is used when GDB is exiting.  It gives less chance of error.
-
-NOTES
-
-       Don't attempt to kill attached inferiors since we may be called
-       when gdb is in the process of aborting, and killing the attached
-       inferior may be very anti-social.  This is particularly true if we
-       were attached just so we could use the /proc facilities to get
-       detailed information about it's status.
-
-*/
-
-void
-kill_inferior_fast ()
-{
-  if (inferior_pid != 0 && !attach_flag)
-    {
-      unconditionally_kill_inferior ();
-    }
-}
-
-/*
-
-GLOBAL FUNCTION
+LOCAL FUNCTION
 
-       kill_inferior - kill any currently inferior
+       procfs_kill_inferior - kill any currently inferior
 
 SYNOPSIS
 
-       void kill_inferior (void)
+       void procfs_kill_inferior (void)
 
 DESCRIPTION
 
@@ -1440,8 +1065,8 @@ NOTES
 
 */
 
-void
-kill_inferior ()
+static void
+procfs_kill_inferior ()
 {
   if (inferior_pid != 0)
     {
@@ -1479,20 +1104,20 @@ unconditionally_kill_inferior ()
   int signo;
   
   signo = SIGKILL;
-  (void) ioctl (pi.fd, PIOCKILL, &signo);
+  ioctl (pi.fd, PIOCKILL, &signo);
   close_proc_file (&pi);
   wait ((int *) 0);
 }
 
 /*
 
-GLOBAL FUNCTION
+LOCAL FUNCTION
 
-       child_xfer_memory -- copy data to or from inferior memory space
+       procfs_xfer_memory -- copy data to or from inferior memory space
 
 SYNOPSIS
 
-       int child_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
+       int procfs_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len,
                int dowrite, struct target_ops target)
 
 DESCRIPTION
@@ -1502,7 +1127,7 @@ DESCRIPTION
        if DOWRITE is zero or to inferior if DOWRITE is nonzero.
   
        Returns the length copied, which is either the LEN argument or
-       zero.  This xfer function does not do partial moves, since child_ops
+       zero.  This xfer function does not do partial moves, since procfs_ops
        doesn't allow memory operations to cross below us in the target stack
        anyway.
 
@@ -1511,9 +1136,8 @@ NOTES
        The /proc interface makes this an almost trivial task.
  */
 
-
-int
-child_xfer_memory (memaddr, myaddr, len, dowrite, target)
+static int
+procfs_xfer_memory (memaddr, myaddr, len, dowrite, target)
      CORE_ADDR memaddr;
      char *myaddr;
      int len;
@@ -1542,13 +1166,13 @@ child_xfer_memory (memaddr, myaddr, len, dowrite, target)
 
 /*
 
-GLOBAL FUNCTION
+LOCAL FUNCTION
 
-       store_inferior_registers -- copy register values back to inferior
+       procfs_store_registers -- copy register values back to inferior
 
 SYNOPSIS
 
-       void store_inferior_registers (int regno)
+       void procfs_store_registers (int regno)
 
 DESCRIPTION
 
@@ -1578,16 +1202,16 @@ NOTES
 
  */
 
-void
-store_inferior_registers (regno)
+static void
+procfs_store_registers (regno)
      int regno;
 {
   if (regno != -1)
     {
-      (void) ioctl (pi.fd, PIOCGREG, &pi.gregset);
+      ioctl (pi.fd, PIOCGREG, &pi.gregset);
     }
   fill_gregset (&pi.gregset, regno);
-  (void) ioctl (pi.fd, PIOCSREG, &pi.gregset);
+  ioctl (pi.fd, PIOCSREG, &pi.gregset);
 
 #if defined (FP0_REGNUM)
 
@@ -1597,10 +1221,10 @@ store_inferior_registers (regno)
 
   if (regno != -1)
     {
-      (void) ioctl (pi.fd, PIOCGFPREG, &pi.fpregset);
+      ioctl (pi.fd, PIOCGFPREG, &pi.fpregset);
     }
   fill_fpregset (&pi.fpregset, regno);
-  (void) ioctl (pi.fd, PIOCSFPREG, &pi.fpregset);
+  ioctl (pi.fd, PIOCSFPREG, &pi.fpregset);
 
 #endif /* FP0_REGNUM */
 
@@ -1608,13 +1232,13 @@ store_inferior_registers (regno)
 
 /*
 
-GLOBAL FUNCTION
+LOCAL FUNCTION
 
-       inferior_proc_init - initialize access to a /proc entry
+       procfs_init_inferior - initialize access to a /proc entry
 
 SYNOPSIS
 
-       void inferior_proc_init (int pid)
+       void procfs_init_inferior (int pid)
 
 DESCRIPTION
 
@@ -1631,19 +1255,22 @@ NOTES
 
  */
 
-void
-inferior_proc_init (pid)
+static void
+procfs_init_inferior (pid)
      int pid;
 {
-  if (!open_proc_file (pid, &pi))
+
+  push_target (&procfs_ops);
+
+  if (!open_proc_file (pid, &pi, O_RDWR))
     {
       proc_init_failed ("can't open process file");
     }
   else
     {
-      (void) memset ((char *) &pi.prrun, 0, sizeof (pi.prrun));
+      memset ((char *) &pi.prrun, 0, sizeof (pi.prrun));
       prfillset (&pi.prrun.pr_trace);
-      proc_signal_handling_change ();
+      procfs_notice_signals ();
       prfillset (&pi.prrun.pr_fault);
       prdelset (&pi.prrun.pr_fault, FLTPAGE);
       if (ioctl (pi.fd, PIOCWSTOP, &pi.prstatus) < 0)
@@ -1661,11 +1288,11 @@ inferior_proc_init (pid)
 
 GLOBAL FUNCTION
 
-       proc_signal_handling_change
+       procfs_notice_signals
 
 SYNOPSIS
 
-       void proc_signal_handling_change (void);
+       static void procfs_notice_signals (void);
 
 DESCRIPTION
 
@@ -1682,8 +1309,8 @@ DESCRIPTION
        involved.
  */
 
-void
-proc_signal_handling_change ()
+static void
+procfs_notice_signals ()
 {
   int signo;
 
@@ -1711,7 +1338,7 @@ proc_signal_handling_change ()
 
 /*
 
-GLOBAL FUNCTION
+LOCAL FUNCTION
 
        proc_set_exec_trap -- arrange for exec'd child to halt at startup
 
@@ -1740,14 +1367,14 @@ NOTE
        tracing flags cleared.
  */
 
-void
+static void
 proc_set_exec_trap ()
 {
   sysset_t exitset;
   auto char procname[32];
   int fd;
   
-  (void) sprintf (procname, PROC_NAME_FMT, getpid ());
+  sprintf (procname, PROC_NAME_FMT, getpid ());
   if ((fd = open (procname, O_RDWR)) < 0)
     {
       perror (procname);
@@ -1781,15 +1408,30 @@ proc_set_exec_trap ()
   /* Turn off inherit-on-fork flag so that all grand-children of gdb
      start with tracing flags cleared. */
 
-#ifdef PIOCRFORK       /* Standard SVR4 */
-  (void) ioctl (fd, PIOCRFORK, NULL);
-#else
-#ifdef PIOCRESET       /* iris (for example) */
+#if defined (PIOCRESET)        /* New method */
   {
       long pr_flags;
       pr_flags = PR_FORK;
-      (void) ioctl (fd, PIOCRESET, &pr_flags);
+      ioctl (fd, PIOCRESET, &pr_flags);
+  }
+#else
+#if defined (PIOCRFORK)        /* Original method */
+  ioctl (fd, PIOCRFORK, NULL);
+#endif
+#endif
+
+  /* Turn on run-on-last-close flag so that this process will not hang
+     if GDB goes away for some reason.  */
+
+#if defined (PIOCSET)  /* New method */
+  {
+      long pr_flags;
+      pr_flags = PR_RLC;
+      (void) ioctl (fd, PIOCSET, &pr_flags);
   }
+#else
+#if defined (PIOCSRLC) /* Original method */
+  (void) ioctl (fd, PIOCSRLC, 0);
 #endif
 #endif
 }
@@ -1822,7 +1464,6 @@ proc_iterate_over_mappings (func)
   int funcstat = 0;
   struct prmap *prmaps;
   struct prmap *prmap;
-  CORE_ADDR baseaddr = 0;
 
   if (pi.valid && (ioctl (pi.fd, PIOCNMAP, &nmap) == 0))
     {
@@ -1840,6 +1481,7 @@ proc_iterate_over_mappings (func)
   return (funcstat);
 }
 
+#if 0  /* Currently unused */
 /*
 
 GLOBAL FUNCTION
@@ -1861,9 +1503,6 @@ DESCRIPTION
        segment containing that address.
 */
 
-
-#if 0  /* Currently unused */
-
 CORE_ADDR
 proc_base_address (addr)
      CORE_ADDR addr;
@@ -1936,17 +1575,117 @@ proc_address_to_fd (addr, complain)
 }
 
 
-#ifdef ATTACH_DETACH
+/* Attach to process PID, then initialize for debugging it
+   and wait for the trace-trap that results from attaching.  */
+
+static void
+procfs_attach (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  char *exec_file;
+  int pid;
+
+  if (!args)
+    error_no_arg ("process-id to attach");
+
+  pid = atoi (args);
+
+  if (pid == getpid())         /* Trying to masturbate? */
+    error ("I refuse to debug myself!");
+
+  if (from_tty)
+    {
+      exec_file = (char *) get_exec_file (0);
+
+      if (exec_file)
+       printf ("Attaching program `%s', pid %d\n", exec_file, pid);
+      else
+       printf ("Attaching pid %d\n", pid);
+
+      fflush (stdout);
+    }
+
+  do_attach (pid);
+  inferior_pid = pid;
+  push_target (&procfs_ops);
+}
+
+
+/* Take a program previously attached to and detaches it.
+   The program resumes execution and will no longer stop
+   on signals, etc.  We'd better not have left any breakpoints
+   in the program or it'll die when it hits one.  For this
+   to work, it may be necessary for the process to have been
+   previously attached.  It *might* work if the program was
+   started via the normal ptrace (PTRACE_TRACEME).  */
+
+static void
+procfs_detach (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  int siggnal = 0;
+
+  if (from_tty)
+    {
+      char *exec_file = get_exec_file (0);
+      if (exec_file == 0)
+       exec_file = "";
+      printf ("Detaching program: %s pid %d\n",
+             exec_file, inferior_pid);
+      fflush (stdout);
+    }
+  if (args)
+    siggnal = atoi (args);
+  
+  do_detach (siggnal);
+  inferior_pid = 0;
+  unpush_target (&procfs_ops);         /* Pop out of handling an inferior */
+}
+
+/* Get ready to modify the registers array.  On machines which store
+   individual registers, this doesn't need to do anything.  On machines
+   which store all the registers in one fell swoop, this makes sure
+   that registers contains all the registers from the program being
+   debugged.  */
+
+static void
+procfs_prepare_to_store ()
+{
+#ifdef CHILD_PREPARE_TO_STORE
+  CHILD_PREPARE_TO_STORE ();
+#endif
+}
+
+/* Print status information about what we're accessing.  */
+
+static void
+procfs_files_info (ignore)
+     struct target_ops *ignore;
+{
+  printf ("\tUsing the running image of %s process %d via /proc.\n",
+         attach_flag? "attached": "child", inferior_pid);
+}
+
+/* ARGSUSED */
+static void
+procfs_open (arg, from_tty)
+     char *arg;
+     int from_tty;
+{
+  error ("Use the \"run\" command to start a Unix child process.");
+}
 
 /*
 
-GLOBAL FUNCTION
+LOCAL FUNCTION
 
-       attach -- attach to an already existing process
+       do_attach -- attach to an already existing process
 
 SYNOPSIS
 
-       int attach (int pid)
+       int do_attach (int pid)
 
 DESCRIPTION
 
@@ -1958,15 +1697,18 @@ NOTES
 
        The option of stopping at attach time is specific to the /proc
        versions of gdb.  Versions using ptrace force the attachee
-       to stop.
+       to stop.  (I have changed this version to do so, too.  All you
+       have to do is "continue" to make it go on. -- gnu@cygnus.com)
 
 */
 
-int
-attach (pid)
+static int
+do_attach (pid)
      int pid;
 {
-  if (!open_proc_file (pid, &pi))
+  int result;
+
+  if (!open_proc_file (pid, &pi, O_RDWR))
     {
       perror_with_name (pi.pathname);
       /* NOTREACHED */
@@ -1989,31 +1731,54 @@ attach (pid)
   else
     {
       pi.was_stopped = 0;
-      if (query ("Process is currently running, stop it? "))
+      if (1 || query ("Process is currently running, stop it? "))
        {
+         /* Make it run again when we close it.  */
+#if defined (PIOCSET)  /* New method */
+         {
+             long pr_flags;
+             pr_flags = PR_RLC;
+             result = ioctl (pi.fd, PIOCSET, &pr_flags);
+         }
+#else
+#if defined (PIOCSRLC) /* Original method */
+         result = ioctl (pi.fd, PIOCSRLC, 0);
+#endif
+#endif
+         if (result < 0)
+           {
+             print_sys_errmsg (pi.pathname, errno);
+             close_proc_file (&pi);
+             error ("PIOCSRLC or PIOCSET failed");
+           }
          if (ioctl (pi.fd, PIOCSTOP, &pi.prstatus) < 0)
            {
              print_sys_errmsg (pi.pathname, errno);
              close_proc_file (&pi);
              error ("PIOCSTOP failed");
            }
+         pi.nopass_next_sigstop = 1;
+       }
+      else
+       {
+         printf ("Ok, gdb will wait for process %u to stop.\n", pid);
        }
     }
-  
+
   /*  Remember some things about the inferior that we will, or might, change
       so that we can restore them when we detach. */
   
-  (void) ioctl (pi.fd, PIOCGTRACE, &pi.saved_trace);
-  (void) ioctl (pi.fd, PIOCGHOLD, &pi.saved_sighold);
-  (void) ioctl (pi.fd, PIOCGFAULT, &pi.saved_fltset);
-  (void) ioctl (pi.fd, PIOCGENTRY, &pi.saved_entryset);
-  (void) ioctl (pi.fd, PIOCGEXIT, &pi.saved_exitset);
+  ioctl (pi.fd, PIOCGTRACE, &pi.saved_trace);
+  ioctl (pi.fd, PIOCGHOLD, &pi.saved_sighold);
+  ioctl (pi.fd, PIOCGFAULT, &pi.saved_fltset);
+  ioctl (pi.fd, PIOCGENTRY, &pi.saved_entryset);
+  ioctl (pi.fd, PIOCGEXIT, &pi.saved_exitset);
   
   /* Set up trace and fault sets, as gdb expects them. */
   
-  (void) memset (&pi.prrun, 0, sizeof (pi.prrun));
+  memset (&pi.prrun, 0, sizeof (pi.prrun));
   prfillset (&pi.prrun.pr_trace);
-  proc_signal_handling_change ();
+  procfs_notice_signals ();
   prfillset (&pi.prrun.pr_fault);
   prdelset (&pi.prrun.pr_fault, FLTPAGE);
   if (ioctl (pi.fd, PIOCSFAULT, &pi.prrun.pr_fault))
@@ -2030,13 +1795,13 @@ attach (pid)
 
 /*
 
-GLOBAL FUNCTION
+LOCAL FUNCTION
 
-       detach -- detach from an attached-to process
+       do_detach -- detach from an attached-to process
 
 SYNOPSIS
 
-       void detach (int signal)
+       void do_detach (int signal)
 
 DESCRIPTION
 
@@ -2057,10 +1822,12 @@ DESCRIPTION
        be the ideal situation.  (FIXME).
  */
 
-void
-detach (signal)
+static void
+do_detach (signal)
      int signal;
 {
+  int result;
+
   if (signal)
     {
       set_proc_siginfo (&pi, signal);
@@ -2102,12 +1869,29 @@ detach (signal)
          if (signal || !pi.was_stopped ||
              query ("Was stopped when attached, make it runnable again? "))
            {
-             (void) memset (&pi.prrun, 0, sizeof (pi.prrun));
-             pi.prrun.pr_flags = PRCFAULT;
-             if (ioctl (pi.fd, PIOCRUN, &pi.prrun))
+             /* Clear any fault that might have stopped it.  */
+             if (ioctl (pi.fd, PIOCCFAULT, 0))
+               {
+                 print_sys_errmsg (pi.pathname, errno);
+                 printf ("PIOCCFAULT failed.\n");
+               }
+
+             /* Make it run again when we close it.  */
+#if defined (PIOCSET)  /* New method */
+             {
+                 long pr_flags;
+                 pr_flags = PR_RLC;
+                 result = ioctl (pi.fd, PIOCSET, &pr_flags);
+             }
+#else
+#if defined (PIOCSRLC) /* Original method */
+             result = ioctl (pi.fd, PIOCSRLC, 0);
+#endif
+#endif
+             if (result)
                {
                  print_sys_errmsg (pi.pathname, errno);
-                 printf ("PIOCRUN failed.\n");
+                 printf ("PIOCSRLC or PIOCSET failed.\n");
                }
            }
        }
@@ -2116,17 +1900,18 @@ detach (signal)
   attach_flag = 0;
 }
 
-#endif /* ATTACH_DETACH */
-
 /*
 
-GLOBAL FUNCTION
+LOCAL FUNCTION
+
+       procfs_wait -- emulate wait() as much as possible
+       Wait for child to do something.  Return pid of child, or -1 in case
+       of error; store status through argument pointer STATUS.
 
-       proc_wait -- emulate wait() as much as possible
 
 SYNOPSIS
 
-       int proc_wait (int *statloc)
+       int procfs_wait (int *statloc)
 
 DESCRIPTION
 
@@ -2155,8 +1940,8 @@ NOTES
 
  */
 
-int
-proc_wait (statloc)
+static int
+procfs_wait (statloc)
      int *statloc;
 {
   short what;
@@ -2171,10 +1956,17 @@ proc_wait (statloc)
     }
   else if (!(pi.prstatus.pr_flags & (PR_STOPPED | PR_ISTOP)))
     {
+      if (attach_flag)
+       set_sigint_trap();      /* Causes SIGINT to be passed on to the
+                                  attached process. */
+
       if (ioctl (pi.fd, PIOCWSTOP, &pi.prstatus) < 0)
        {
          checkerr++;
        }
+
+      if (attach_flag)
+       clear_sigint_trap();
     }    
   if (checkerr)
     {
@@ -2183,6 +1975,7 @@ proc_wait (statloc)
          rtnval = wait (&statval);
          if (rtnval != inferior_pid)
            {
+             print_sys_errmsg (pi.pathname, errno);
              error ("PIOCWSTOP, wait failed, returned %d", rtnval);
              /* NOTREACHED */
            }
@@ -2271,10 +2064,19 @@ proc_wait (statloc)
             pi.prstatus.pr_flags);
          /* NOTREACHED */
     }
+
   if (statloc)
     {
       *statloc = statval;
     }
+
+  if (rtnval == -1)            /* No more children to wait for */
+    {
+      fprintf (stderr, "Child process unexpectedly missing.\n");
+      *statloc = 42;   /* Claim it exited with signal 42 */
+      return rtnval;
+    }
+
   return (rtnval);
 }
 
@@ -2332,7 +2134,7 @@ set_proc_siginfo (pip, signo)
        }
       else
        {
-         (void) memset ((char *) &newsiginfo, 0, sizeof (newsiginfo));
+         memset ((char *) &newsiginfo, 0, sizeof (newsiginfo));
          sip = &newsiginfo;
          sip -> si_signo = signo;
          sip -> si_code = 0;
@@ -2350,13 +2152,13 @@ set_proc_siginfo (pip, signo)
 
 /*
 
-GLOBAL FUNCTION
+LOCAL FUNCTION
 
-       child_resume -- resume execution of the inferior process
+       procfs_resume -- resume execution of the inferior process
 
 SYNOPSIS
 
-       void child_resume (int step, int signo)
+       void procfs_resume (int step, int signo)
 
 DESCRIPTION
 
@@ -2371,17 +2173,38 @@ NOTE
        to be current.  One case where this might be necessary is if the
        user explicitly changes the PC value that gdb considers to be
        current.  FIXME:  Investigate if this is necessary or not.
+
+       When attaching to a child process, if we forced it to stop with
+       a PIOCSTOP, then we will have set the nopass_next_sigstop flag.
+       Upon resuming the first time after such a stop, we explicitly
+       inhibit sending it another SIGSTOP, which would be the normal
+       result of default signal handling.  One potential drawback to
+       this is that we will also ignore any attempt to by the user
+       to explicitly continue after the attach with a SIGSTOP.  Ultimately
+       this problem should be dealt with by making the routines that
+       deal with the inferior a little smarter, and possibly even allow
+       an inferior to continue running at the same time as gdb.  (FIXME?)
  */
 
-void
-child_resume (step, signo)
+static void
+procfs_resume (step, signo)
      int step;
      int signo;
 {
   errno = 0;
-  pi.prrun.pr_flags = PRSVADDR | PRSTRACE | PRSFAULT | PRCFAULT;
+  pi.prrun.pr_flags = PRSTRACE | PRSFAULT | PRCFAULT;
+
+#ifdef PRSVADDR_BROKEN
+/* Can't do this under Solaris running on a Sparc, as there seems to be no
+   place to put nPC.  In fact, if you use this, nPC seems to be set to some
+   random garbage.  We have to rely on the fact that PC and nPC have been
+   written previously via PIOCSREG during a register flush. */
+
   pi.prrun.pr_vaddr = (caddr_t) *(int *) &registers[REGISTER_BYTE (PC_REGNUM)];
-  if (signo)
+  pi.prrun.pr_flags != PRSVADDR;
+#endif
+
+  if (signo && !(signo == SIGSTOP && pi.nopass_next_sigstop))
     {
       set_proc_siginfo (&pi, signo);
     }
@@ -2389,6 +2212,7 @@ child_resume (step, signo)
     {
       pi.prrun.pr_flags |= PRCSIG;
     }
+  pi.nopass_next_sigstop = 0;
   if (step)
     {
       pi.prrun.pr_flags |= PRSTEP;
@@ -2402,13 +2226,13 @@ child_resume (step, signo)
 
 /*
 
-GLOBAL FUNCTION
+LOCAL FUNCTION
 
-       fetch_inferior_registers -- fetch current registers from inferior
+       procfs_fetch_registers -- fetch current registers from inferior
 
 SYNOPSIS
 
-       void fetch_inferior_registers (int regno)
+       void procfs_fetch_registers (int regno)
 
 DESCRIPTION
 
@@ -2418,8 +2242,8 @@ DESCRIPTION
 
 */
 
-void
-fetch_inferior_registers (regno)
+static void
+procfs_fetch_registers (regno)
      int regno;
 {
   if (ioctl (pi.fd, PIOCGREG, &pi.gregset) != -1)
@@ -2436,68 +2260,6 @@ fetch_inferior_registers (regno)
 
 /*
 
-GLOBAL FUNCTION
-
-       fetch_core_registers -- fetch current registers from core file data
-
-SYNOPSIS
-
-       void fetch_core_registers (char *core_reg_sect, unsigned core_reg_size,
-                                  int which, unsigned in reg_addr)
-
-DESCRIPTION
-
-       Read the values of either the general register set (WHICH equals 0)
-       or the floating point register set (WHICH equals 2) from the core
-       file data (pointed to by CORE_REG_SECT), and update gdb's idea of
-       their current values.  The CORE_REG_SIZE parameter is ignored.
-
-NOTES
-
-       Use the indicated sizes to validate the gregset and fpregset
-       structures.
-*/
-
-void
-fetch_core_registers (core_reg_sect, core_reg_size, which, reg_addr)
-     char *core_reg_sect;
-     unsigned core_reg_size;
-     int which;
-     unsigned int reg_addr;    /* Unused in this version */
-{
-
-  if (which == 0)
-    {
-      if (core_reg_size != sizeof (pi.gregset))
-       {
-         warning ("wrong size gregset struct in core file");
-       }
-      else
-       {
-         (void) memcpy ((char *) &pi.gregset, core_reg_sect,
-                        sizeof (pi.gregset));
-         supply_gregset (&pi.gregset);
-       }
-    }
-  else if (which == 2)
-    {
-      if (core_reg_size != sizeof (pi.fpregset))
-       {
-         warning ("wrong size fpregset struct in core file");
-       }
-      else
-       {
-         (void) memcpy ((char *) &pi.fpregset, core_reg_sect,
-                        sizeof (pi.fpregset));
-#if defined (FP0_REGNUM)
-         supply_fpregset (&pi.fpregset);
-#endif
-       }
-    }
-}
-
-/*
-
 LOCAL FUNCTION
 
        proc_init_failed - called whenever /proc access initialization fails
@@ -2519,7 +2281,7 @@ proc_init_failed (why)
      char *why;
 {
   print_sys_errmsg (pi.pathname, errno);
-  (void) kill (pi.pid, SIGKILL);
+  kill (pi.pid, SIGKILL);
   close_proc_file (&pi);
   error (why);
   /* NOTREACHED */
@@ -2551,7 +2313,7 @@ close_proc_file (pip)
   pip -> pid = 0;
   if (pip -> valid)
     {
-      (void) close (pip -> fd);
+      close (pip -> fd);
     }
   pip -> fd = -1;
   if (pip -> pathname)
@@ -2570,15 +2332,16 @@ LOCAL FUNCTION
 
 SYNOPSIS
 
-       static int open_proc_file (pid, struct procinfo *pip)
+       static int open_proc_file (int pid, struct procinfo *pip, int mode)
 
 DESCRIPTION
 
-       Given a process id, close the existing open /proc entry (if any)
-       and open one for the new process id.  Once it is open, then
-       mark the local process information structure as valid, which
-       guarantees that the pid, fd, and pathname fields match an open
-       /proc entry.  Returns zero if the open fails, nonzero otherwise.
+       Given a process id and a mode, close the existing open /proc
+       entry (if any) and open one for the new process id, in the
+       specified mode.  Once it is open, then mark the local process
+       information structure as valid, which guarantees that the pid,
+       fd, and pathname fields match an open /proc entry.  Returns
+       zero if the open fails, nonzero otherwise.
 
        Note that the pathname is left intact, even when the open fails,
        so that callers can use it to construct meaningful error messages
@@ -2586,21 +2349,22 @@ DESCRIPTION
  */
 
 static int
-open_proc_file (pid, pip)
+open_proc_file (pid, pip, mode)
      int pid;
      struct procinfo *pip;
+     int mode;
 {
-  pip -> valid = 0;
+  pip -> valid = 0;            /* FIXME, what is this? ?!  */
   if (pip -> valid)
     {
-      (void) close (pip -> fd);
+      close (pip -> fd);
     }
   if (pip -> pathname == NULL)
     {
       pip -> pathname = xmalloc (32);
     }
   sprintf (pip -> pathname, PROC_NAME_FMT, pid);
-  if ((pip -> fd = open (pip -> pathname, O_RDWR)) >= 0)
+  if ((pip -> fd = open (pip -> pathname, mode)) >= 0)
     {
       pip -> valid = 1;
       pip -> pid = pid;
@@ -2612,15 +2376,18 @@ static char *
 mappingflags (flags)
      long flags;
 {
-  static char asciiflags[7];
+  static char asciiflags[8];
   
-  strcpy (asciiflags, "------");
-  if (flags & MA_STACK)  asciiflags[0] = 's';
-  if (flags & MA_BREAK)  asciiflags[1] = 'b';
-  if (flags & MA_SHARED) asciiflags[2] = 's';
-  if (flags & MA_READ)   asciiflags[3] = 'r';
-  if (flags & MA_WRITE)  asciiflags[4] = 'w';
-  if (flags & MA_EXEC)   asciiflags[5] = 'x';
+  strcpy (asciiflags, "-------");
+#if defined (MA_PHYS)
+  if (flags & MA_PHYS)   asciiflags[0] = 'd';
+#endif
+  if (flags & MA_STACK)  asciiflags[1] = 's';
+  if (flags & MA_BREAK)  asciiflags[2] = 'b';
+  if (flags & MA_SHARED) asciiflags[3] = 's';
+  if (flags & MA_READ)   asciiflags[4] = 'r';
+  if (flags & MA_WRITE)  asciiflags[5] = 'w';
+  if (flags & MA_EXEC)   asciiflags[6] = 'x';
   return (asciiflags);
 }
 
@@ -2706,7 +2473,7 @@ info_proc_stop (pip, summary)
            else
              {
                printf_filtered ("\t%-16s %s.\n", signalname (what),
-                                sys_siglist[what]);
+                                safe_strsignal (what));
              }
            break;
          case PR_SYSENTRY:
@@ -2767,8 +2534,7 @@ info_proc_siginfo (pip, summary)
          printf_filtered ("%s ", signalname (sip -> si_signo));
          if (sip -> si_errno > 0)
            {
-             printf_filtered ("%s ", lookupname (errno_table,
-                                                 sip -> si_errno, "errno"));
+             printf_filtered ("%s ", errnoname (sip -> si_errno));
            }
          if (sip -> si_code <= 0)
            {
@@ -2801,13 +2567,12 @@ info_proc_siginfo (pip, summary)
        {
          printf_filtered ("\n\n");
          printf_filtered ("\t%-16s %s.\n", signalname (sip -> si_signo),
-                          sys_siglist[sip -> si_signo]);
+                          safe_strsignal (sip -> si_signo));
          if (sip -> si_errno > 0)
            {
              printf_filtered ("\t%-16s %s.\n",
-                              lookupname (errno_table,
-                                          sip -> si_errno, "errno"),
-                              lookupdesc (errno_table, sip -> si_errno));
+                              errnoname (sip -> si_errno),
+                              safe_strerror (sip -> si_errno));
            }
          if (sip -> si_code <= 0)
            {
@@ -2918,17 +2683,36 @@ static char *
 signalname (signo)
      int signo;
 {
-  char *abbrev;
+  char *name;
   static char locbuf[32];
 
-  abbrev = sig_abbrev (signo);
-  if (abbrev == NULL)
+  name = strsigno (signo);
+  if (name == NULL)
     {
-      sprintf (locbuf, "signal %d", signo);
+      sprintf (locbuf, "Signal %d", signo);
     }
   else
     {
-      sprintf (locbuf, "SIG%s (%d)", abbrev, signo);
+      sprintf (locbuf, "%s (%d)", name, signo);
+    }
+  return (locbuf);
+}
+
+static char *
+errnoname (errnum)
+     int errnum;
+{
+  char *name;
+  static char locbuf[32];
+
+  name = strerrno (errnum);
+  if (name == NULL)
+    {
+      sprintf (locbuf, "Errno %d", errnum);
+    }
+  else
+    {
+      sprintf (locbuf, "%s (%d)", name, errnum);
     }
   return (locbuf);
 }
@@ -2964,7 +2748,7 @@ info_proc_signals (pip, summary)
          printf_filtered ("%-8s ",
                           prismember (&pip -> prstatus.pr_sigpend, signo)
                           ? "yes" : "no");
-         printf_filtered (" %s\n", sys_siglist[signo]);
+         printf_filtered (" %s\n", safe_strsignal (signo));
        }
       printf_filtered ("\n");
     }
@@ -3012,7 +2796,7 @@ info_proc_mappings (pip, summary)
   if (!summary)
     {
       printf_filtered ("Mapped address spaces:\n\n");
-      printf_filtered ("\t%10s %10s %10s %10s %6s\n",
+      printf_filtered ("\t%10s %10s %10s %10s %7s\n",
                       "Start Addr",
                       "  End Addr",
                       "      Size",
@@ -3025,7 +2809,7 @@ info_proc_mappings (pip, summary)
            {
              for (prmap = prmaps; prmap -> pr_size; ++prmap)
                {
-                 printf_filtered ("\t%#10x %#10x %#10x %#10x %6s\n",
+                 printf_filtered ("\t%#10x %#10x %#10x %#10x %7s\n",
                                   prmap -> pr_vaddr,
                                   prmap -> pr_vaddr + prmap -> pr_size - 1,
                                   prmap -> pr_size,
@@ -3060,7 +2844,9 @@ DESCRIPTION
        info proc mappings      (prints address mappings)
        info proc times         (prints process/children times)
        info proc id            (prints pid, ppid, gid, sid, etc)
+               FIXME:  i proc id not implemented.
        info proc status        (prints general process state info)
+               FIXME:  i proc status not implemented.
        info proc signals       (prints info about signal handling)
        info proc all           (prints all info)
 
@@ -3075,7 +2861,6 @@ info_proc (args, from_tty)
   struct procinfo pii;
   struct procinfo *pip;
   struct cleanup *old_chain;
-  char *nexttok;
   char **argv;
   int argsize;
   int summary = 1;
@@ -3155,8 +2940,8 @@ info_proc (args, from_tty)
            {
              pid = pii.pid;
              pip = &pii;
-             (void) memset (&pii, 0, sizeof (pii));
-             if (!open_proc_file (pid, pip))
+             memset (&pii, 0, sizeof (pii));
+             if (!open_proc_file (pid, pip, O_RDONLY))
                {
                  perror_with_name (pip -> pathname);
                  /* NOTREACHED */
@@ -3176,7 +2961,8 @@ info_proc (args, from_tty)
 
   if (!pip -> valid)
     {
-      error ("No process.  Run an inferior or specify an explicit pid.");
+      error ("\
+No process.  Start debugging a program or specify an explicit process ID.");
     }
   if (ioctl (pip -> fd, PIOCSTATUS, &(pip -> prstatus)) < 0)
     {
@@ -3224,15 +3010,87 @@ info_proc (args, from_tty)
   do_cleanups (old_chain);
 }
 
+/* Fork an inferior process, and start debugging it with /proc.  */
+
+static void
+procfs_create_inferior (exec_file, allargs, env)
+     char *exec_file;
+     char *allargs;
+     char **env;
+{
+  fork_inferior (exec_file, allargs, env,
+                proc_set_exec_trap, procfs_init_inferior);
+  /* We are at the first instruction we care about.  */
+  /* Pedal to the metal... */
+  proceed ((CORE_ADDR) -1, 0, 0);
+}
+
+/* Clean up after the inferior dies.  */
+
+static void
+procfs_mourn_inferior ()
+{
+  unpush_target (&procfs_ops);
+  generic_mourn_inferior ();
+}
+
+/* Mark our target-struct as eligible for stray "run" and "attach" commands.  */
+static int
+procfs_can_run ()
+{
+  return(1);
+}
+\f
+struct target_ops procfs_ops = {
+  "procfs",                    /* to_shortname */
+  "Unix /proc child process",  /* to_longname */
+  "Unix /proc child process (started by the \"run\" command).",        /* to_doc */
+  procfs_open,                 /* to_open */
+  0,                           /* to_close */
+  procfs_attach,                       /* to_attach */
+  procfs_detach,               /* to_detach */
+  procfs_resume,                       /* to_resume */
+  procfs_wait,                 /* to_wait */
+  procfs_fetch_registers,      /* to_fetch_registers */
+  procfs_store_registers,      /* to_store_registers */
+  procfs_prepare_to_store,     /* to_prepare_to_store */
+  procfs_xfer_memory,          /* to_xfer_memory */
+  procfs_files_info,           /* to_files_info */
+  memory_insert_breakpoint,    /* to_insert_breakpoint */
+  memory_remove_breakpoint,    /* to_remove_breakpoint */
+  terminal_init_inferior,      /* to_terminal_init */
+  terminal_inferior,           /* to_terminal_inferior */
+  terminal_ours_for_output,    /* to_terminal_ours_for_output */
+  terminal_ours,               /* to_terminal_ours */
+  child_terminal_info,         /* to_terminal_info */
+  procfs_kill_inferior,                /* to_kill */
+  0,                           /* to_load */
+  0,                           /* to_lookup_symbol */
+  procfs_create_inferior,      /* to_create_inferior */
+  procfs_mourn_inferior,       /* to_mourn_inferior */
+  procfs_can_run,              /* to_can_run */
+  procfs_notice_signals,       /* to_notice_signals */
+  process_stratum,             /* to_stratum */
+  0,                           /* to_next */
+  1,                           /* to_has_all_memory */
+  1,                           /* to_has_memory */
+  1,                           /* to_has_stack */
+  1,                           /* to_has_registers */
+  1,                           /* to_has_execution */
+  0,                           /* sections */
+  0,                           /* sections_end */
+  OPS_MAGIC                    /* to_magic */
+};
+
 /*
 
 GLOBAL FUNCTION
 
-       _initialize_proc_fs -- initialize the process file system stuff
+       _initialize_procfs -- initialize the process file system stuff
 
 SYNOPSIS
 
-       void _initialize_proc_fs (void)
+       void _initialize_procfs (void)
 
 DESCRIPTION
 
@@ -3241,19 +3099,18 @@ DESCRIPTION
 
 */
 
-static char *proc_desc =
+void
+_initialize_procfs ()
+{
+  add_target (&procfs_ops);
+
+  add_info ("proc", info_proc, 
 "Show process status information using /proc entry.\n\
 Specify process id or use current inferior by default.\n\
 Specify keywords for detailed information; default is summary.\n\
 Keywords are: `all', `faults', `flags', `id', `mappings', `signals',\n\
 `status', `syscalls', and `times'.\n\
-Unambiguous abbreviations may be used.";
+Unambiguous abbreviations may be used.");
 
-void
-_initialize_proc_fs ()
-{
-  add_info ("proc", info_proc, proc_desc);
   init_syscall_table ();
 }
-
-#endif /* USE_PROC_FS */
This page took 0.043961 seconds and 4 git commands to generate.