]> code.delx.au - gnu-emacs/blobdiff - src/process.c
*** empty log message ***
[gnu-emacs] / src / process.c
index a93958a0f845f6fc9aee0509d6dbac39127eac0b..dbb431496c3c34e8d3bf9f2f6f93b4f6391c4c3d 100644 (file)
@@ -1,6 +1,7 @@
 /* Asynchronous subprocess control for GNU Emacs.
-   Copyright (C) 1985, 86, 87, 88, 93, 94, 95, 96, 98, 1999,
-      2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995,
+                 1996, 1998, 1999, 2001, 2002, 2003, 2004,
+                 2005, 2006 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -16,8 +17,8 @@ GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with GNU Emacs; see the file COPYING.  If not, write to
-the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
 
 
 #include <config.h>
@@ -39,6 +40,9 @@ Boston, MA 02111-1307, USA.  */
 #include <sys/types.h>         /* some typedefs are used in sys/file.h */
 #include <sys/file.h>
 #include <sys/stat.h>
+#ifdef HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
@@ -117,10 +121,18 @@ Boston, MA 02111-1307, USA.  */
 #include <sys/wait.h>
 #endif
 
+/* Disable IPv6 support for w32 until someone figures out how to do it
+   properly.  */
+#ifdef WINDOWSNT
+# ifdef AF_INET6
+#  undef AF_INET6
+# endif
+#endif
+
+#include "lisp.h"
 #include "systime.h"
 #include "systty.h"
 
-#include "lisp.h"
 #include "window.h"
 #include "buffer.h"
 #include "charset.h"
@@ -139,7 +151,10 @@ Boston, MA 02111-1307, USA.  */
 Lisp_Object Qprocessp;
 Lisp_Object Qrun, Qstop, Qsignal;
 Lisp_Object Qopen, Qclosed, Qconnect, Qfailed, Qlisten;
-Lisp_Object Qlocal, Qdatagram;
+Lisp_Object Qlocal, Qipv4, Qdatagram;
+#ifdef AF_INET6
+Lisp_Object Qipv6;
+#endif
 Lisp_Object QCname, QCbuffer, QChost, QCservice, QCtype;
 Lisp_Object QClocal, QCremote, QCcoding;
 Lisp_Object QCserver, QCnowait, QCnoquery, QCstop;
@@ -186,7 +201,6 @@ extern Lisp_Object QCfilter;
 
 #include "syswait.h"
 
-extern void set_waiting_for_input P_ ((EMACS_TIME *));
 extern char *get_operating_system_release ();
 
 #ifndef USE_CRT_DLL
@@ -272,17 +286,19 @@ int update_tick;
 #define READ_OUTPUT_DELAY_MAX       (READ_OUTPUT_DELAY_INCREMENT * 5)
 #define READ_OUTPUT_DELAY_MAX_MAX   (READ_OUTPUT_DELAY_INCREMENT * 7)
 
-/* Number of processes which might be delayed.  */
+/* Number of processes which have a non-zero read_output_delay,
+   and therefore might be delayed for adaptive read buffering.  */
 
 static int process_output_delay_count;
 
-/* Non-zero if any process has non-nil process_output_skip.  */
+/* Non-zero if any process has non-nil read_output_skip.  */
 
 static int process_output_skip;
 
 /* Non-nil means to delay reading process output to improve buffering.
    A value of t means that delay is reset after each send, any other
-   non-nil value does not reset the delay.  */
+   non-nil value does not reset the delay.  A value of nil disables
+   adaptive read buffering completely.  */
 static Lisp_Object Vprocess_adaptive_read_buffering;
 #else
 #define process_output_delay_count 0
@@ -291,7 +307,10 @@ static Lisp_Object Vprocess_adaptive_read_buffering;
 
 #include "sysselect.h"
 
-extern int keyboard_bit_set P_ ((SELECT_TYPE *));
+static int keyboard_bit_set P_ ((SELECT_TYPE *));
+static void deactivate_process P_ ((Lisp_Object));
+static void status_notify P_ ((struct Lisp_Process *));
+static int read_process_output P_ ((Lisp_Object, int));
 
 /* If we support a window system, turn on the code to poll periodically
    to detect C-g.  It isn't actually used when doing interrupt input.  */
@@ -376,8 +395,6 @@ extern int timers_run;
 /* Maximum number of bytes to send to a pty without an eof.  */
 static int pty_max_bytes;
 
-extern Lisp_Object Vfile_name_coding_system, Vdefault_file_name_coding_system;
-
 #ifdef HAVE_PTYS
 #ifdef HAVE_PTY_H
 #include <pty.h>
@@ -390,23 +407,23 @@ static char pty_name[24];
 /* Compute the Lisp form of the process status, p->status, from
    the numeric status that was returned by `wait'.  */
 
-Lisp_Object status_convert ();
+static Lisp_Object status_convert ();
 
-void
+static void
 update_status (p)
      struct Lisp_Process *p;
 {
   union { int i; WAITTYPE wt; } u;
-  u.i = XFASTINT (p->raw_status_low) + (XFASTINT (p->raw_status_high) << 16);
+  eassert (p->raw_status_new);
+  u.i = p->raw_status;
   p->status = status_convert (u.wt);
-  p->raw_status_low = Qnil;
-  p->raw_status_high = Qnil;
+  p->raw_status_new = 0;
 }
 
 /*  Convert a process status word in Unix format to
     the list that we use internally.  */
 
-Lisp_Object
+static Lisp_Object
 status_convert (w)
      WAITTYPE w;
 {
@@ -425,7 +442,7 @@ status_convert (w)
 /* Given a status-list, extract the three pieces of information
    and store them individually through the three pointers.  */
 
-void
+static void
 decode_status (l, symbol, code, coredump)
      Lisp_Object l;
      Lisp_Object *symbol;
@@ -504,7 +521,7 @@ status_message (p)
    The file name of the terminal corresponding to the pty
    is left in the variable pty_name.  */
 
-int
+static int
 allocate_pty ()
 {
   register int c, i;
@@ -589,7 +606,7 @@ allocate_pty ()
 }
 #endif /* HAVE_PTYS */
 \f
-Lisp_Object
+static Lisp_Object
 make_process (name)
      Lisp_Object name;
 {
@@ -602,11 +619,10 @@ make_process (name)
 
   XSETINT (p->infd, -1);
   XSETINT (p->outfd, -1);
-  XSETFASTINT (p->pid, 0);
   XSETFASTINT (p->tick, 0);
   XSETFASTINT (p->update_tick, 0);
-  p->raw_status_low = Qnil;
-  p->raw_status_high = Qnil;
+  p->pid = 0;
+  p->raw_status_new = 0;
   p->status = Qrun;
   p->mark = Fmake_marker ();
 
@@ -633,7 +649,7 @@ make_process (name)
   return val;
 }
 
-void
+static void
 remove_process (proc)
      register Lisp_Object proc;
 {
@@ -767,23 +783,26 @@ nil, indicating the current buffer's process.  */)
      (process)
      register Lisp_Object process;
 {
+  register struct Lisp_Process *p;
+
   process = get_process (process);
-  XPROCESS (process)->raw_status_low = Qnil;
-  XPROCESS (process)->raw_status_high = Qnil;
-  if (NETCONN_P (process))
+  p = XPROCESS (process);
+
+  p->raw_status_new = 0;
+  if (NETCONN1_P (p))
     {
-      XPROCESS (process)->status = Fcons (Qexit, Fcons (make_number (0), Qnil));
-      XSETINT (XPROCESS (process)->tick, ++process_tick);
-      status_notify ();
+      p->status = Fcons (Qexit, Fcons (make_number (0), Qnil));
+      XSETINT (p->tick, ++process_tick);
+      status_notify (p);
     }
-  else if (XINT (XPROCESS (process)->infd) >= 0)
+  else if (XINT (p->infd) >= 0)
     {
       Fkill_process (process, Qnil);
       /* Do this now, since remove_process will make sigchld_handler do nothing.  */
-      XPROCESS (process)->status
+      p->status
        = Fcons (Qsignal, Fcons (make_number (SIGKILL), Qnil));
-      XSETINT (XPROCESS (process)->tick, ++process_tick);
-      status_notify ();
+      XSETINT (p->tick, ++process_tick);
+      status_notify (p);
     }
   remove_process (process);
   return Qnil;
@@ -819,7 +838,7 @@ nil, indicating the current buffer's process.  */)
     return process;
 
   p = XPROCESS (process);
-  if (!NILP (p->raw_status_low))
+  if (p->raw_status_new)
     update_status (p);
   status = p->status;
   if (CONSP (status))
@@ -844,7 +863,7 @@ If PROCESS has not yet exited or died, return 0.  */)
      register Lisp_Object process;
 {
   CHECK_PROCESS (process);
-  if (!NILP (XPROCESS (process)->raw_status_low))
+  if (XPROCESS (process)->raw_status_new)
     update_status (XPROCESS (process));
   if (CONSP (XPROCESS (process)->status))
     return XCAR (XCDR (XPROCESS (process)->status));
@@ -859,7 +878,9 @@ For a network connection, this value is nil.  */)
      register Lisp_Object process;
 {
   CHECK_PROCESS (process);
-  return XPROCESS (process)->pid;
+  return (XPROCESS (process)->pid
+         ? make_fixnum_or_float (XPROCESS (process)->pid)
+         : Qnil);
 }
 
 DEFUN ("process-name", Fprocess_name, Sprocess_name, 1, 1, 0,
@@ -1188,9 +1209,11 @@ a socket connection.  */)
 DEFUN ("format-network-address", Fformat_network_address, Sformat_network_address,
        1, 2, 0,
        doc: /* Convert network ADDRESS from internal format to a string.
+A 4 or 5 element vector represents an IPv4 address (with port number).
+An 8 or 9 element vector represents an IPv6 address (with port number).
 If optional second argument OMIT-PORT is non-nil, don't include a port
-number in the string; in this case, interpret a 4 element vector as an
-IP address.  Returns nil if format of ADDRESS is invalid.  */)
+number in the string, even when present in ADDRESS.
+Returns nil if format of ADDRESS is invalid.  */)
      (address, omit_port)
      Lisp_Object address, omit_port;
 {
@@ -1200,13 +1223,13 @@ IP address.  Returns nil if format of ADDRESS is invalid.  */)
   if (STRINGP (address))  /* AF_LOCAL */
     return address;
 
-  if (VECTORP (address))  /* AF_INET */
+  if (VECTORP (address))  /* AF_INET or AF_INET6 */
     {
       register struct Lisp_Vector *p = XVECTOR (address);
       Lisp_Object args[6];
       int nargs, i;
 
-      if (!NILP (omit_port) && (p->size == 4 || p->size == 5))
+      if (p->size == 4 || (p->size == 5 && !NILP (omit_port)))
        {
          args[0] = build_string ("%d.%d.%d.%d");
          nargs = 4;
@@ -1216,6 +1239,16 @@ IP address.  Returns nil if format of ADDRESS is invalid.  */)
          args[0] = build_string ("%d.%d.%d.%d:%d");
          nargs = 5;
        }
+      else if (p->size == 8 || (p->size == 9 && !NILP (omit_port)))
+       {
+         args[0] = build_string ("%x:%x:%x:%x:%x:%x:%x:%x");
+         nargs = 8;
+       }
+      else if (p->size == 9)
+       {
+         args[0] = build_string ("[%x:%x:%x:%x:%x:%x:%x:%x]:%d");
+         nargs = 9;
+       }
       else
        return Qnil;
 
@@ -1237,7 +1270,7 @@ IP address.  Returns nil if format of ADDRESS is invalid.  */)
 }
 #endif
 \f
-Lisp_Object
+static Lisp_Object
 list_processes_1 (query_only)
      Lisp_Object query_only;
 {
@@ -1329,7 +1362,7 @@ list_processes_1 (query_only)
       Finsert (1, &p->name);
       Findent_to (i_status, minspace);
 
-      if (!NILP (p->raw_status_low))
+      if (p->raw_status_new)
        update_status (p);
       symbol = p->status;
       if (CONSP (p->status))
@@ -1537,7 +1570,6 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS)  */)
 
   XPROCESS (proc)->childp = Qt;
   XPROCESS (proc)->plist = Qnil;
-  XPROCESS (proc)->command_channel_p = Qnil;
   XPROCESS (proc)->buffer = buffer;
   XPROCESS (proc)->sentinel = Qnil;
   XPROCESS (proc)->filter = Qnil;
@@ -1550,7 +1582,7 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS)  */)
 #endif
 
   /* Make the process marker point into the process buffer (if any).  */
-  if (!NILP (buffer))
+  if (BUFFERP (buffer))
     set_marker_both (XPROCESS (proc)->mark, buffer,
                     BUF_ZV (XBUFFER (buffer)),
                     BUF_ZV_BYTE (XBUFFER (buffer)));
@@ -1702,13 +1734,13 @@ start_process_unwind (proc)
     abort ();
 
   /* Was PROC started successfully?  */
-  if (XINT (XPROCESS (proc)->pid) <= 0)
+  if (XPROCESS (proc)->pid <= 0)
     remove_process (proc);
 
   return Qnil;
 }
 
-void
+static void
 create_process_1 (timer)
      struct atimer *timer;
 {
@@ -1786,6 +1818,12 @@ create_process (process, new_argv, current_dir)
 #endif
       if (forkin < 0)
        report_file_error ("Opening pty", Qnil);
+#if defined (RTU) || defined (UNIPLUS) || defined (DONT_REOPEN_PTY)
+      /* In the case that vfork is defined as fork, the parent process
+        (Emacs) may send some data before the child process completes
+        tty options setup.  So we setup tty before forking.  */
+      child_setup_tty (forkout);
+#endif /* RTU or UNIPLUS or DONT_REOPEN_PTY */
 #else
       forkin = forkout = -1;
 #endif /* not USG, or USG_SUBTTY_WORKS */
@@ -1907,7 +1945,7 @@ create_process (process, new_argv, current_dir)
      in the table after this function has returned; if it does
      it might cause call-process to hang and subsequent asynchronous
      processes to get their return values scrambled.  */
-  XSETINT (XPROCESS (process)->pid, -1);
+  XPROCESS (process)->pid = -1;
 
   BLOCK_INPUT;
 
@@ -2070,8 +2108,10 @@ create_process (process, new_argv, current_dir)
 #endif /* SIGCHLD */
 #endif /* !POSIX_SIGNALS */
 
+#if !defined (RTU) && !defined (UNIPLUS) && !defined (DONT_REOPEN_PTY)
        if (pty_flag)
          child_setup_tty (xforkout);
+#endif /* not RTU and not UNIPLUS and not DONT_REOPEN_PTY */
 #ifdef WINDOWSNT
        pid = child_setup (xforkin, xforkout, xforkout,
                           new_argv, 1, current_dir);
@@ -2096,7 +2136,7 @@ create_process (process, new_argv, current_dir)
   else
     {
       /* vfork succeeded.  */
-      XSETFASTINT (XPROCESS (process)->pid, pid);
+      XPROCESS (process)->pid = pid;
 
 #ifdef WINDOWSNT
       register_child (pid, inchannel);
@@ -2198,6 +2238,20 @@ conv_sockaddr_to_lisp (sa, len)
        cp = (unsigned char *)&sin->sin_addr;
        break;
       }
+#ifdef AF_INET6
+    case AF_INET6:
+      {
+       struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa;
+       uint16_t *ip6 = (uint16_t *)&sin6->sin6_addr;
+       len = sizeof (sin6->sin6_addr)/2 + 1;
+       address = Fmake_vector (make_number (len), Qnil);
+       p = XVECTOR (address);
+       p->contents[--len] = make_number (ntohs (sin6->sin6_port));
+       for (i = 0; i < len; i++)
+         p->contents[i] = make_number (ntohs (ip6[i]));
+       return address;
+      }
+#endif
 #ifdef HAVE_LOCAL_SOCKETS
     case AF_LOCAL:
       {
@@ -2242,6 +2296,13 @@ get_lisp_to_sockaddr_size (address, familyp)
          *familyp = AF_INET;
          return sizeof (struct sockaddr_in);
        }
+#ifdef AF_INET6
+      else if (p->size == 9)
+       {
+         *familyp = AF_INET6;
+         return sizeof (struct sockaddr_in6);
+       }
+#endif
     }
 #ifdef HAVE_LOCAL_SOCKETS
   else if (STRINGP (address))
@@ -2261,7 +2322,11 @@ get_lisp_to_sockaddr_size (address, familyp)
 }
 
 /* Convert an address object (vector or string) to an internal sockaddr.
-   Format of address has already been validated by size_lisp_to_sockaddr.  */
+
+   The address format has been basically validated by
+   get_lisp_to_sockaddr_size, but this does not mean FAMILY is valid;
+   it could have come from user data.  So if FAMILY is not valid,
+   we return after zeroing *SA.  */
 
 static void
 conv_lisp_to_sockaddr (family, address, sa, len)
@@ -2275,7 +2340,6 @@ conv_lisp_to_sockaddr (family, address, sa, len)
   register int i;
 
   bzero (sa, len);
-  sa->sa_family = family;
 
   if (VECTORP (address))
     {
@@ -2287,7 +2351,26 @@ conv_lisp_to_sockaddr (family, address, sa, len)
          i = XINT (p->contents[--len]);
          sin->sin_port = htons (i);
          cp = (unsigned char *)&sin->sin_addr;
+         sa->sa_family = family;
+       }
+#ifdef AF_INET6
+      else if (family == AF_INET6)
+       {
+         struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa;
+         uint16_t *ip6 = (uint16_t *)&sin6->sin6_addr;
+         len = sizeof (sin6->sin6_addr) + 1;
+         i = XINT (p->contents[--len]);
+         sin6->sin6_port = htons (i);
+         for (i = 0; i < len; i++)
+           if (INTEGERP (p->contents[i]))
+             {
+               int j = XFASTINT (p->contents[i]) & 0xffff;
+               ip6[i] = ntohs (j);
+             }
+         sa->sa_family = family;
        }
+#endif
+      return;
     }
   else if (STRINGP (address))
     {
@@ -2298,6 +2381,7 @@ conv_lisp_to_sockaddr (family, address, sa, len)
          cp = SDATA (address);
          for (i = 0; i < sizeof (sockun->sun_path) && *cp; i++)
            sockun->sun_path[i] = *cp++;
+         sa->sa_family = family;
        }
 #endif
       return;
@@ -2531,7 +2615,7 @@ OPTION is not a supported option, return nil instead; otherwise return t.  */)
 \f
 /* A version of request_sigio suitable for a record_unwind_protect.  */
 
-Lisp_Object
+static Lisp_Object
 unwind_request_sigio (dummy)
      Lisp_Object dummy;
 {
@@ -2553,7 +2637,7 @@ DEFUN ("make-network-process", Fmake_network_process, Smake_network_process,
 In Emacs, network connections are represented by process objects, so
 input and output work as for subprocesses and `delete-process' closes
 a network connection.  However, a network process has no process id,
-it cannot be signalled, and the status codes are different from normal
+it cannot be signaled, and the status codes are different from normal
 processes.
 
 Arguments are specified as keyword/argument pairs.  The following
@@ -2581,10 +2665,13 @@ a random port number is selected for the server.
 stream type connection, `datagram' creates a datagram type connection.
 
 :family FAMILY -- FAMILY is the address (and protocol) family for the
-service specified by HOST and SERVICE.  The default address family is
-Inet (or IPv4) for the host and port number specified by HOST and
-SERVICE.  Other address families supported are:
+service specified by HOST and SERVICE.  The default (nil) is to use
+whatever address family (IPv4 or IPv6) that is defined for the host
+and port number specified by HOST and SERVICE.  Other address families
+supported are:
   local -- for a local (i.e. UNIX) address specified by SERVICE.
+  ipv4  -- use IPv4 address family only.
+  ipv6  -- use IPv6 address family only.
 
 :local ADDRESS -- ADDRESS is the local address used for the connection.
 This parameter is ignored when opening a client process. When specified
@@ -2701,8 +2788,8 @@ usage: (make-network-process &rest ARGS)  */)
   struct Lisp_Process *p;
 #ifdef HAVE_GETADDRINFO
   struct addrinfo ai, *res, *lres;
-      struct addrinfo hints;
-      char *portstring, portbuf[128];
+  struct addrinfo hints;
+  char *portstring, portbuf[128];
 #else /* HAVE_GETADDRINFO */
   struct _emacs_addrinfo
   {
@@ -2841,19 +2928,29 @@ usage: (make-network-process &rest ARGS)  */)
 
   /* :family FAMILY -- nil (for Inet), local, or integer.  */
   tem = Fplist_get (contact, QCfamily);
-  if (INTEGERP (tem))
-    family = XINT (tem);
-  else
+  if (NILP (tem))
     {
-      if (NILP (tem))
-       family = AF_INET;
-#ifdef HAVE_LOCAL_SOCKETS
-      else if (EQ (tem, Qlocal))
-       family = AF_LOCAL;
+#if defined(HAVE_GETADDRINFO) && defined(AF_INET6)
+      family = AF_UNSPEC;
+#else
+      family = AF_INET;
 #endif
     }
-  if (family < 0)
+#ifdef HAVE_LOCAL_SOCKETS
+  else if (EQ (tem, Qlocal))
+    family = AF_LOCAL;
+#endif
+#ifdef AF_INET6
+  else if (EQ (tem, Qipv6))
+    family = AF_INET6;
+#endif
+  else if (EQ (tem, Qipv4))
+    family = AF_INET;
+  else if (INTEGERP (tem))
+    family = XINT (tem);
+  else
     error ("Unknown address family");
+
   ai.ai_family = family;
 
   /* :service SERVICE -- string, integer (port number), or t (random port).  */
@@ -2919,7 +3016,7 @@ usage: (make-network-process &rest ARGS)  */)
       QUIT;
       memset (&hints, 0, sizeof (hints));
       hints.ai_flags = 0;
-      hints.ai_family = NILP (Fplist_member (contact, QCfamily)) ? AF_UNSPEC : family;
+      hints.ai_family = family;
       hints.ai_socktype = socktype;
       hints.ai_protocol = 0;
       ret = getaddrinfo (SDATA (host), portstring, &hints, &res);
@@ -3258,12 +3355,18 @@ usage: (make-network-process &rest ARGS)  */)
     p->kill_without_query = Qt;
   if ((tem = Fplist_get (contact, QCstop), !NILP (tem)))
     p->command = Qt;
-  p->pid = Qnil;
+  p->pid = 0;
   XSETINT (p->infd, inch);
   XSETINT (p->outfd, outch);
   if (is_server && socktype == SOCK_STREAM)
     p->status = Qlisten;
 
+  /* Make the process marker point into the process buffer (if any).  */
+  if (BUFFERP (buffer))
+    set_marker_both (p->mark, buffer,
+                    BUF_ZV (XBUFFER (buffer)),
+                    BUF_ZV_BYTE (XBUFFER (buffer)));
+
 #ifdef NON_BLOCKING_CONNECT
   if (is_non_blocking_client)
     {
@@ -3507,6 +3610,21 @@ static struct ifflag_def ifflag_table[] = {
 #endif
 #ifdef IFF_DYNAMIC
   { IFF_DYNAMIC,       "dynamic" },
+#endif
+#ifdef IFF_OACTIVE
+  { IFF_OACTIVE,       "oactive" },    /* OpenBSD: transmission in progress */
+#endif
+#ifdef IFF_SIMPLEX
+  { IFF_SIMPLEX,       "simplex" },    /* OpenBSD: can't hear own transmissions */
+#endif
+#ifdef IFF_LINK0
+  { IFF_LINK0,         "link0" },      /* OpenBSD: per link layer defined bit */
+#endif
+#ifdef IFF_LINK1
+  { IFF_LINK1,         "link1" },      /* OpenBSD: per link layer defined bit */
+#endif
+#ifdef IFF_LINK2
+  { IFF_LINK2,         "link2" },      /* OpenBSD: per link layer defined bit */
 #endif
   { 0, 0 }
 };
@@ -3544,7 +3662,7 @@ FLAGS is the current flags of the interface.  */)
       int fnum;
 
       any++;
-      for (fp = ifflag_table; flags != 0 && fp; fp++)
+      for (fp = ifflag_table; flags != 0 && fp->flag_sym; fp++)
        {
          if (flags & fp->flag_bit)
            {
@@ -3580,11 +3698,15 @@ FLAGS is the current flags of the interface.  */)
   res = Fcons (elt, res);
 
   elt = Qnil;
-#if defined(SIOCGIFNETMASK) && defined(ifr_netmask)
+#if defined(SIOCGIFNETMASK) && (defined(HAVE_STRUCT_IFREQ_IFR_NETMASK) || defined(HAVE_STRUCT_IFREQ_IFR_ADDR))
   if (ioctl (s, SIOCGIFNETMASK, &rq) == 0)
     {
       any++;
+#ifdef HAVE_STRUCT_IFREQ_IFR_NETMASK
       elt = conv_sockaddr_to_lisp (&rq.ifr_netmask, sizeof (rq.ifr_netmask));
+#else
+      elt = conv_sockaddr_to_lisp (&rq.ifr_addr, sizeof (rq.ifr_addr));
+#endif
     }
 #endif
   res = Fcons (elt, res);
@@ -3722,62 +3844,60 @@ DEFUN ("accept-process-output", Faccept_process_output, Saccept_process_output,
 It is read into the process' buffers or given to their filter functions.
 Non-nil arg PROCESS means do not return until some output has been received
 from PROCESS.
-Non-nil second arg TIMEOUT and third arg TIMEOUT-MSECS are number of
-seconds and microseconds to wait; return after that much time whether
-or not there is input.
+
+Non-nil second arg SECONDS and third arg MILLISEC are number of
+seconds and milliseconds to wait; return after that much time whether
+or not there is input.  If SECONDS is a floating point number,
+it specifies a fractional number of seconds to wait.
+
 If optional fourth arg JUST-THIS-ONE is non-nil, only accept output
 from PROCESS, suspending reading output from other processes.
 If JUST-THIS-ONE is an integer, don't run any timers either.
 Return non-nil iff we received any output before the timeout expired.  */)
-     (process, timeout, timeout_msecs, just_this_one)
-     register Lisp_Object process, timeout, timeout_msecs, just_this_one;
+     (process, seconds, millisec, just_this_one)
+     register Lisp_Object process, seconds, millisec, just_this_one;
 {
-  int seconds;
-  int useconds;
+  int secs, usecs = 0;
 
   if (! NILP (process))
     CHECK_PROCESS (process);
   else
     just_this_one = Qnil;
 
-  if (! NILP (timeout_msecs))
+  if (!NILP (seconds))
     {
-      CHECK_NUMBER (timeout_msecs);
-      useconds = XINT (timeout_msecs);
-      if (!INTEGERP (timeout))
-       XSETINT (timeout, 0);
-
-      {
-       int carry = useconds / 1000000;
+      if (INTEGERP (seconds))
+       secs = XINT (seconds);
+      else if (FLOATP (seconds))
+       {
+         double timeout = XFLOAT_DATA (seconds);
+         secs = (int) timeout;
+         usecs = (int) ((timeout - (double) secs) * 1000000);
+       }
+      else
+       wrong_type_argument (Qnumberp, seconds);
 
-       XSETINT (timeout, XINT (timeout) + carry);
-       useconds -= carry * 1000000;
+      if (INTEGERP (millisec))
+       {
+         int carry;
+         usecs += XINT (millisec) * 1000;
+         carry = usecs / 1000000;
+         secs += carry;
+         if ((usecs -= carry * 1000000) < 0)
+           {
+             secs--;
+             usecs += 1000000;
+           }
+       }
 
-       /* I think this clause is necessary because C doesn't
-          guarantee a particular rounding direction for negative
-          integers.  */
-       if (useconds < 0)
-         {
-           XSETINT (timeout, XINT (timeout) - 1);
-           useconds += 1000000;
-         }
-      }
+      if (secs < 0 || (secs == 0 && usecs == 0))
+       secs = -1, usecs = 0;
     }
   else
-    useconds = 0;
-
-  if (! NILP (timeout))
-    {
-      CHECK_NUMBER (timeout);
-      seconds = XINT (timeout);
-      if (seconds < 0 || (seconds == 0 && useconds == 0))
-       seconds = -1;
-    }
-  else
-    seconds = NILP (process) ? -1 : 0;
+    secs = NILP (process) ? -1 : 0;
 
   return
-    (wait_reading_process_output (seconds, useconds, 0, 0,
+    (wait_reading_process_output (secs, usecs, 0, 0,
                                  Qnil,
                                  !NILP (process) ? XPROCESS (process) : NULL,
                                  NILP (just_this_one) ? 0 :
@@ -3802,6 +3922,9 @@ server_accept_connection (server, channel)
   union u_sockaddr {
     struct sockaddr sa;
     struct sockaddr_in in;
+#ifdef AF_INET6
+    struct sockaddr_in6 in6;
+#endif
 #ifdef HAVE_LOCAL_SOCKETS
     struct sockaddr_un un;
 #endif
@@ -3858,6 +3981,26 @@ server_accept_connection (server, channel)
       }
       break;
 
+#ifdef AF_INET6
+    case AF_INET6:
+      {
+       Lisp_Object args[9];
+       uint16_t *ip6 = (uint16_t *)&saddr.in6.sin6_addr;
+       int i;
+       args[0] = build_string ("%x:%x:%x:%x:%x:%x:%x:%x");
+       for (i = 0; i < 8; i++)
+         args[i+1] = make_number (ntohs(ip6[i]));
+       host = Fformat (9, args);
+       service = make_number (ntohs (saddr.in.sin_port));
+
+       args[0] = build_string (" <[%s]:%d>");
+       args[1] = host;
+       args[2] = service;
+       caller = Fformat (3, args);
+      }
+      break;
+#endif
+
 #ifdef HAVE_LOCAL_SOCKETS
     case AF_LOCAL:
 #endif
@@ -3928,7 +4071,7 @@ server_accept_connection (server, channel)
   p->sentinel = ps->sentinel;
   p->filter = ps->filter;
   p->command = Qnil;
-  p->pid = Qnil;
+  p->pid = 0;
   XSETINT (p->infd, s);
   XSETINT (p->outfd, s);
   p->status = Qrun;
@@ -4222,15 +4365,15 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
              /* It's okay for us to do this and then continue with
                 the loop, since timeout has already been zeroed out.  */
              clear_waiting_for_input ();
-             status_notify ();
+             status_notify (NULL);
            }
        }
 
       /* Don't wait for output from a non-running process.  Just
          read whatever data has already been received.  */
-      if (wait_proc != 0 && !NILP (wait_proc->raw_status_low))
+      if (wait_proc && wait_proc->raw_status_new)
        update_status (wait_proc);
-      if (wait_proc != 0
+      if (wait_proc
          && ! EQ (wait_proc->status, Qrun)
          && ! EQ (wait_proc->status, Qconnect))
        {
@@ -4321,6 +4464,11 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
 #endif
 
 #ifdef ADAPTIVE_READ_BUFFERING
+         /* Set the timeout for adaptive read buffering if any
+            process has non-nil read_output_skip and non-zero
+            read_output_delay, and we are not reading output for a
+            specific wait_channel.  It is not executed if
+            Vprocess_adaptive_read_buffering is nil.  */
          if (process_output_skip && check_delay > 0)
            {
              int usecs = EMACS_USECS (timeout);
@@ -4331,6 +4479,8 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
                  proc = chan_process[channel];
                  if (NILP (proc))
                    continue;
+                 /* Find minimum non-zero read_output_delay among the
+                    processes with non-nil read_output_skip.  */
                  if (XINT (XPROCESS (proc)->read_output_delay) > 0)
                    {
                      check_delay--;
@@ -4607,7 +4757,7 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
                  /* Preserve status of processes already terminated.  */
                  XSETINT (XPROCESS (proc)->tick, ++process_tick);
                  deactivate_process (proc);
-                 if (!NILP (XPROCESS (proc)->raw_status_low))
+                 if (XPROCESS (proc)->raw_status_new)
                    update_status (XPROCESS (proc));
                  if (EQ (XPROCESS (proc)->status, Qrun))
                    XPROCESS (proc)->status
@@ -4733,7 +4883,7 @@ read_process_output_error_handler (error)
    The characters read are decoded according to PROC's coding-system
    for decoding.  */
 
-int
+static int
 read_process_output (proc, channel)
      Lisp_Object proc;
      register int channel;
@@ -4881,10 +5031,10 @@ read_process_output (proc, channel)
        {
          Lisp_Object tem;
          /* Don't clobber the CURRENT match data, either!  */
-         tem = Fmatch_data (Qnil, Qnil);
-         restore_match_data ();
-         record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
-         Fset_match_data (tem);
+         tem = Fmatch_data (Qnil, Qnil, Qnil);
+         restore_search_regs ();
+         record_unwind_save_match_data ();
+         Fset_match_data (tem, Qt);
        }
 
       /* For speed, if a search happens within this code,
@@ -4938,7 +5088,7 @@ read_process_output (proc, channel)
                                   read_process_output_error_handler);
 
       /* If we saved the match data nonrecursively, restore it now.  */
-      restore_match_data ();
+      restore_search_regs ();
       running_asynch_code = outer_running_asynch_code;
 
       /* Handling the process output should not deactivate the mark.  */
@@ -5110,6 +5260,7 @@ send_process_trap ()
   sigrelse (SIGPIPE);
   sigrelse (SIGALRM);
 #endif /* BSD4_1 */
+  sigunblock (sigmask (SIGPIPE));
   longjmp (send_process_frame, 1);
 }
 
@@ -5123,7 +5274,7 @@ send_process_trap ()
 
    This function can evaluate Lisp code and can garbage collect.  */
 
-void
+static void
 send_process (proc, buf, len, object)
      volatile Lisp_Object proc;
      unsigned char *volatile buf;
@@ -5135,6 +5286,7 @@ send_process (proc, buf, len, object)
   int rv;
   struct coding_system *coding;
   struct gcpro gcpro1;
+  SIGTYPE (*volatile old_sigpipe) ();
 
   GCPRO1 (object);
 
@@ -5142,7 +5294,7 @@ send_process (proc, buf, len, object)
   VMS_PROC_STUFF *vs, *get_vms_process_pointer();
 #endif /* VMS */
 
-  if (! NILP (p->raw_status_low))
+  if (p->raw_status_new)
     update_status (p);
   if (! EQ (p->status, Qrun))
     error ("Process %s not running", SDATA (p->name));
@@ -5259,7 +5411,6 @@ send_process (proc, buf, len, object)
       while (len > 0)
        {
          int this = len;
-         SIGTYPE (*old_sigpipe)();
 
          /* Decide how much data we can send in one batch.
             Long lines need to be split into multiple batches.  */
@@ -5301,7 +5452,11 @@ send_process (proc, buf, len, object)
                               0, datagram_address[outfd].sa,
                               datagram_address[outfd].len);
                  if (rv < 0 && errno == EMSGSIZE)
-                   report_file_error ("sending datagram", Fcons (proc, Qnil));
+                   {
+                     signal (SIGPIPE, old_sigpipe);
+                     report_file_error ("sending datagram",
+                                        Fcons (proc, Qnil));
+                   }
                }
              else
 #endif
@@ -5398,12 +5553,12 @@ send_process (proc, buf, len, object)
 #endif /* not VMS */
   else
     {
+      signal (SIGPIPE, old_sigpipe);
 #ifndef VMS
       proc = process_sent_to;
       p = XPROCESS (proc);
 #endif
-      p->raw_status_low = Qnil;
-      p->raw_status_high = Qnil;
+      p->raw_status_new = 0;
       p->status = Fcons (Qexit, Fcons (make_number (256), Qnil));
       XSETINT (p->tick, ++process_tick);
       deactivate_process (proc);
@@ -5518,7 +5673,7 @@ return t unconditionally.  */)
 
   gid = emacs_get_tty_pgrp (p);
 
-  if (gid == XFASTINT (p->pid))
+  if (gid == p->pid)
     return Qnil;
   return Qt;
 }
@@ -5565,7 +5720,7 @@ process_send_signal (process, signo, current_group, nomsg)
   /* If we are using pgrps, get a pgrp number and make it negative.  */
   if (NILP (current_group))
     /* Send the signal to the shell's process group.  */
-    gid = XFASTINT (p->pid);
+    gid = p->pid;
   else
     {
 #ifdef SIGNALS_VIA_CHARACTERS
@@ -5684,7 +5839,7 @@ process_send_signal (process, signo, current_group, nomsg)
       if (gid == -1)
        /* If we can't get the information, assume
           the shell owns the tty.  */
-       gid = XFASTINT (p->pid);
+       gid = p->pid;
 
       /* It is not clear whether anything really can set GID to -1.
         Perhaps on some system one of those ioctls can or could do so.
@@ -5694,12 +5849,12 @@ process_send_signal (process, signo, current_group, nomsg)
 #else  /* ! defined (TIOCGPGRP ) */
       /* Can't select pgrps on this system, so we know that
         the child itself heads the pgrp.  */
-      gid = XFASTINT (p->pid);
+      gid = p->pid;
 #endif /* ! defined (TIOCGPGRP ) */
 
       /* If current_group is lambda, and the shell owns the terminal,
         don't send any signal.  */
-      if (EQ (current_group, Qlambda) && gid == XFASTINT (p->pid))
+      if (EQ (current_group, Qlambda) && gid == p->pid)
        return;
     }
 
@@ -5707,12 +5862,11 @@ process_send_signal (process, signo, current_group, nomsg)
     {
 #ifdef SIGCONT
     case SIGCONT:
-      p->raw_status_low = Qnil;
-      p->raw_status_high = Qnil;
+      p->raw_status_new = 0;
       p->status = Qrun;
       XSETINT (p->tick, ++process_tick);
       if (!nomsg)
-       status_notify ();
+       status_notify (NULL);
       break;
 #endif /* ! defined (SIGCONT) */
     case SIGINT:
@@ -5727,7 +5881,7 @@ process_send_signal (process, signo, current_group, nomsg)
 #endif
     case SIGKILL:
 #ifdef VMS
-      sys$forcex (&(XFASTINT (p->pid)), 0, 1);
+      sys$forcex (&(p->pid), 0, 1);
       whoosh:
 #endif
       flush_pending_output (XINT (p->infd));
@@ -5739,7 +5893,7 @@ process_send_signal (process, signo, current_group, nomsg)
      obvious alternative.  */
   if (no_pgrp)
     {
-      kill (XFASTINT (p->pid), signo);
+      kill (p->pid, signo);
       return;
     }
 
@@ -5752,7 +5906,7 @@ process_send_signal (process, signo, current_group, nomsg)
     }
   else
     {
-      gid = - XFASTINT (p->pid);
+      gid = - p->pid;
       kill (gid, signo);
     }
 #else /* ! defined (TIOCSIGSEND) */
@@ -5823,7 +5977,7 @@ If PROCESS is a network process, inhibit handling of incoming traffic.  */)
     }
 #endif
 #ifndef SIGTSTP
-  error ("no SIGTSTP support");
+  error ("No SIGTSTP support");
 #else
   process_send_signal (process, SIGTSTP, current_group, 0);
 #endif
@@ -5857,7 +6011,7 @@ If PROCESS is a network process, resume handling of incoming traffic.  */)
 #ifdef SIGCONT
     process_send_signal (process, SIGCONT, current_group, 0);
 #else
-    error ("no SIGCONT support");
+    error ("No SIGCONT support");
 #endif
   return process;
 }
@@ -5872,11 +6026,17 @@ SIGCODE may be an integer, or a symbol whose name is a signal name.  */)
      (process, sigcode)
      Lisp_Object process, sigcode;
 {
-  Lisp_Object pid;
+  pid_t pid;
 
   if (INTEGERP (process))
     {
-      pid = process;
+      pid = XINT (process);
+      goto got_it;
+    }
+
+  if (FLOATP (process))
+    {
+      pid = (pid_t) XFLOAT (process);
       goto got_it;
     }
 
@@ -5885,8 +6045,8 @@ SIGCODE may be an integer, or a symbol whose name is a signal name.  */)
       Lisp_Object tem;
       if (tem = Fget_process (process), NILP (tem))
        {
-         pid = Fstring_to_number (process, make_number (10));
-         if (XINT (pid) != 0)
+         pid = XINT (Fstring_to_number (process, make_number (10)));
+         if (pid > 0)
            goto got_it;
        }
       process = tem;
@@ -5899,7 +6059,7 @@ SIGCODE may be an integer, or a symbol whose name is a signal name.  */)
 
   CHECK_PROCESS (process);
   pid = XPROCESS (process)->pid;
-  if (!INTEGERP (pid) || XINT (pid) <= 0)
+  if (pid <= 0)
     error ("Cannot signal process %s", SDATA (XPROCESS (process)->name));
 
  got_it:
@@ -5917,97 +6077,100 @@ SIGCODE may be an integer, or a symbol whose name is a signal name.  */)
       CHECK_SYMBOL (sigcode);
       name = SDATA (SYMBOL_NAME (sigcode));
 
+      if (!strncmp(name, "SIG", 3))
+       name += 3;
+
       if (0)
        ;
 #ifdef SIGHUP
-      handle_signal ("SIGHUP", SIGHUP);
+      handle_signal ("HUP", SIGHUP);
 #endif
 #ifdef SIGINT
-      handle_signal ("SIGINT", SIGINT);
+      handle_signal ("INT", SIGINT);
 #endif
 #ifdef SIGQUIT
-      handle_signal ("SIGQUIT", SIGQUIT);
+      handle_signal ("QUIT", SIGQUIT);
 #endif
 #ifdef SIGILL
-      handle_signal ("SIGILL", SIGILL);
+      handle_signal ("ILL", SIGILL);
 #endif
 #ifdef SIGABRT
-      handle_signal ("SIGABRT", SIGABRT);
+      handle_signal ("ABRT", SIGABRT);
 #endif
 #ifdef SIGEMT
-      handle_signal ("SIGEMT", SIGEMT);
+      handle_signal ("EMT", SIGEMT);
 #endif
 #ifdef SIGKILL
-      handle_signal ("SIGKILL", SIGKILL);
+      handle_signal ("KILL", SIGKILL);
 #endif
 #ifdef SIGFPE
-      handle_signal ("SIGFPE", SIGFPE);
+      handle_signal ("FPE", SIGFPE);
 #endif
 #ifdef SIGBUS
-      handle_signal ("SIGBUS", SIGBUS);
+      handle_signal ("BUS", SIGBUS);
 #endif
 #ifdef SIGSEGV
-      handle_signal ("SIGSEGV", SIGSEGV);
+      handle_signal ("SEGV", SIGSEGV);
 #endif
 #ifdef SIGSYS
-      handle_signal ("SIGSYS", SIGSYS);
+      handle_signal ("SYS", SIGSYS);
 #endif
 #ifdef SIGPIPE
-      handle_signal ("SIGPIPE", SIGPIPE);
+      handle_signal ("PIPE", SIGPIPE);
 #endif
 #ifdef SIGALRM
-      handle_signal ("SIGALRM", SIGALRM);
+      handle_signal ("ALRM", SIGALRM);
 #endif
 #ifdef SIGTERM
-      handle_signal ("SIGTERM", SIGTERM);
+      handle_signal ("TERM", SIGTERM);
 #endif
 #ifdef SIGURG
-      handle_signal ("SIGURG", SIGURG);
+      handle_signal ("URG", SIGURG);
 #endif
 #ifdef SIGSTOP
-      handle_signal ("SIGSTOP", SIGSTOP);
+      handle_signal ("STOP", SIGSTOP);
 #endif
 #ifdef SIGTSTP
-      handle_signal ("SIGTSTP", SIGTSTP);
+      handle_signal ("TSTP", SIGTSTP);
 #endif
 #ifdef SIGCONT
-      handle_signal ("SIGCONT", SIGCONT);
+      handle_signal ("CONT", SIGCONT);
 #endif
 #ifdef SIGCHLD
-      handle_signal ("SIGCHLD", SIGCHLD);
+      handle_signal ("CHLD", SIGCHLD);
 #endif
 #ifdef SIGTTIN
-      handle_signal ("SIGTTIN", SIGTTIN);
+      handle_signal ("TTIN", SIGTTIN);
 #endif
 #ifdef SIGTTOU
-      handle_signal ("SIGTTOU", SIGTTOU);
+      handle_signal ("TTOU", SIGTTOU);
 #endif
 #ifdef SIGIO
-      handle_signal ("SIGIO", SIGIO);
+      handle_signal ("IO", SIGIO);
 #endif
 #ifdef SIGXCPU
-      handle_signal ("SIGXCPU", SIGXCPU);
+      handle_signal ("XCPU", SIGXCPU);
 #endif
 #ifdef SIGXFSZ
-      handle_signal ("SIGXFSZ", SIGXFSZ);
+      handle_signal ("XFSZ", SIGXFSZ);
 #endif
 #ifdef SIGVTALRM
-      handle_signal ("SIGVTALRM", SIGVTALRM);
+      handle_signal ("VTALRM", SIGVTALRM);
 #endif
 #ifdef SIGPROF
-      handle_signal ("SIGPROF", SIGPROF);
+      handle_signal ("PROF", SIGPROF);
 #endif
 #ifdef SIGWINCH
-      handle_signal ("SIGWINCH", SIGWINCH);
+      handle_signal ("WINCH", SIGWINCH);
 #endif
 #ifdef SIGINFO
-      handle_signal ("SIGINFO", SIGINFO);
+      handle_signal ("INFO", SIGINFO);
 #endif
 #ifdef SIGUSR1
-      handle_signal ("SIGUSR1", SIGUSR1);
+      handle_signal ("USR1", SIGUSR1);
 #endif
 #ifdef SIGUSR2
-      handle_signal ("SIGUSR2", SIGUSR2);
+      handle_signal ("USR2", SIGUSR2);
 #endif
       else
        error ("Undefined signal name %s", name);
@@ -6015,7 +6178,7 @@ SIGCODE may be an integer, or a symbol whose name is a signal name.  */)
 
 #undef handle_signal
 
-  return make_number (kill (XINT (pid), XINT (sigcode)));
+  return make_number (kill (pid, XINT (sigcode)));
 }
 
 DEFUN ("process-send-eof", Fprocess_send_eof, Sprocess_send_eof, 0, 1, 0,
@@ -6039,7 +6202,7 @@ text to PROCESS after you call this function.  */)
   coding = proc_encode_coding_system[XINT (XPROCESS (proc)->outfd)];
 
   /* Make sure the process is really alive.  */
-  if (! NILP (XPROCESS (proc)->raw_status_low))
+  if (XPROCESS (proc)->raw_status_new)
     update_status (XPROCESS (proc));
   if (! EQ (XPROCESS (proc)->status, Qrun))
     error ("Process %s not running", SDATA (XPROCESS (proc)->name));
@@ -6064,7 +6227,7 @@ text to PROCESS after you call this function.  */)
         for communication with the subprocess, call shutdown to cause EOF.
         (In some old system, shutdown to socketpair doesn't work.
         Then we just can't win.)  */
-      if (NILP (XPROCESS (proc)->pid)
+      if (XPROCESS (proc)->pid == 0
          || XINT (XPROCESS (proc)->outfd) == XINT (XPROCESS (proc)->infd))
        shutdown (XINT (XPROCESS (proc)->outfd), 1);
       /* In case of socketpair, outfd == infd, so don't close it.  */
@@ -6074,6 +6237,8 @@ text to PROCESS after you call this function.  */)
       emacs_close (XINT (XPROCESS (proc)->outfd));
 #endif /* not HAVE_SHUTDOWN */
       new_outfd = emacs_open (NULL_DEVICE, O_WRONLY, 0);
+      if (new_outfd < 0)
+       abort ();
       old_outfd = XINT (XPROCESS (proc)->outfd);
 
       if (!proc_encode_coding_system[new_outfd])
@@ -6201,7 +6366,7 @@ sigchld_handler (signo)
        {
          proc = XCDR (XCAR (tail));
          p = XPROCESS (proc);
-         if (GC_EQ (p->childp, Qt) && XINT (p->pid) == pid)
+         if (GC_EQ (p->childp, Qt) && p->pid == pid)
            break;
          p = 0;
        }
@@ -6213,7 +6378,7 @@ sigchld_handler (signo)
          {
            proc = XCDR (XCAR (tail));
            p = XPROCESS (proc);
-           if (GC_INTEGERP (p->pid) && XINT (p->pid) == -1)
+           if (p->pid == -1)
              break;
            p = 0;
          }
@@ -6226,8 +6391,8 @@ sigchld_handler (signo)
 
          XSETINT (p->tick, ++process_tick);
          u.wt = w;
-         XSETINT (p->raw_status_low, u.i & 0xffff);
-         XSETINT (p->raw_status_high, u.i >> 16);
+         p->raw_status = u.i;
+         p->raw_status_new = 1;
 
          /* If process has terminated, stop waiting for its output.  */
          if ((WIFSIGNALED (w) || WIFEXITED (w))
@@ -6336,10 +6501,10 @@ exec_sentinel (proc, reason)
   if (outer_running_asynch_code)
     {
       Lisp_Object tem;
-      tem = Fmatch_data (Qnil, Qnil);
-      restore_match_data ();
-      record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
-      Fset_match_data (tem);
+      tem = Fmatch_data (Qnil, Qnil, Qnil);
+      restore_search_regs ();
+      record_unwind_save_match_data ();
+      Fset_match_data (tem, Qt);
     }
 
   /* For speed, if a search happens within this code,
@@ -6353,7 +6518,7 @@ exec_sentinel (proc, reason)
                             exec_sentinel_error_handler);
 
   /* If we saved the match data nonrecursively, restore it now.  */
-  restore_match_data ();
+  restore_search_regs ();
   running_asynch_code = outer_running_asynch_code;
 
   Vdeactivate_mark = odeactivate;
@@ -6380,8 +6545,9 @@ exec_sentinel (proc, reason)
    This is usually done while Emacs is waiting for keyboard input
    but can be done at other times.  */
 
-void
-status_notify ()
+static void
+status_notify (deleting_process)
+     struct Lisp_Process *deleting_process;
 {
   register Lisp_Object proc, buffer;
   Lisp_Object tail, msg;
@@ -6417,12 +6583,13 @@ status_notify ()
                 && ! EQ (p->status, Qlisten)
                 && ! EQ (p->command, Qt)  /* Network process not stopped.  */
                 && XINT (p->infd) >= 0
+                && p != deleting_process
                 && read_process_output (proc, XINT (p->infd)) > 0);
 
          buffer = p->buffer;
 
          /* Get the text to use for the message.  */
-         if (!NILP (p->raw_status_low))
+         if (p->raw_status_new)
            update_status (p);
          msg = status_message (p);
 
@@ -6620,7 +6787,7 @@ delete_keyboard_wait_descriptor (desc)
 /* Return nonzero if *MASK has a bit set
    that corresponds to one of the keyboard input descriptors.  */
 
-int
+static int
 keyboard_bit_set (mask)
      SELECT_TYPE *mask;
 {
@@ -6691,6 +6858,10 @@ init_process ()
 #endif
 #ifdef HAVE_LOCAL_SOCKETS
    ADD_SUBFEATURE (QCfamily, Qlocal);
+#endif
+   ADD_SUBFEATURE (QCfamily, Qipv4);
+#ifdef AF_INET6
+   ADD_SUBFEATURE (QCfamily, Qipv6);
 #endif
 #ifdef HAVE_GETSOCKNAME
    ADD_SUBFEATURE (QCservice, Qt);
@@ -6707,7 +6878,7 @@ init_process ()
 #endif /* HAVE_SOCKETS */
 
 #if defined (DARWIN) || defined (MAC_OSX)
-  /* PTYs are broken on Darwin < 6, but are sometimes useful for interactive 
+  /* PTYs are broken on Darwin < 6, but are sometimes useful for interactive
      processes.  As such, we only change the default value.  */
  if (initialized)
   {
@@ -6750,6 +6921,12 @@ syms_of_process ()
   staticpro (&Qlisten);
   Qlocal = intern ("local");
   staticpro (&Qlocal);
+  Qipv4 = intern ("ipv4");
+  staticpro (&Qipv4);
+#ifdef AF_INET6
+  Qipv6 = intern ("ipv6");
+  staticpro (&Qipv6);
+#endif
   Qdatagram = intern ("datagram");
   staticpro (&Qdatagram);
 
@@ -6812,9 +6989,9 @@ The value takes effect when `start-process' is called.  */);
               doc: /* If non-nil, improve receive buffering by delaying after short reads.
 On some systems, when Emacs reads the output from a subprocess, the output data
 is read in very small blocks, potentially resulting in very poor performance.
-This behaviour can be remedied to some extent by setting this variable to a
+This behavior can be remedied to some extent by setting this variable to a
 non-nil value, as it will automatically delay reading from such processes, to
-allowing them to produce more output before Emacs tries to read it.
+allow them to produce more output before Emacs tries to read it.
 If the value is t, the delay is reset after each write to the process; any other
 non-nil value means that the delay is not reset on write.
 The variable takes effect when `start-process' is called.  */);