]> code.delx.au - gnu-emacs/blobdiff - src/process.c
*** empty log message ***
[gnu-emacs] / src / process.c
index c683e7b8516e214ca94374c25b367adef0c2a326..ebe8ef56fff55a2678a7fa8be42c380d632481b2 100644 (file)
@@ -1,7 +1,7 @@
 /* Asynchronous subprocess control for GNU Emacs.
    Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995,
                  1996, 1998, 1999, 2001, 2002, 2003, 2004,
 /* Asynchronous subprocess control for GNU Emacs.
    Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995,
                  1996, 1998, 1999, 2001, 2002, 2003, 2004,
-                 2005 Free Software Foundation, Inc.
+                 2005, 2006 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 
 This file is part of GNU Emacs.
 
@@ -40,6 +40,9 @@ Boston, MA 02110-1301, USA.  */
 #include <sys/types.h>         /* some typedefs are used in sys/file.h */
 #include <sys/file.h>
 #include <sys/stat.h>
 #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
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
 #endif
@@ -118,10 +121,18 @@ Boston, MA 02110-1301, USA.  */
 #include <sys/wait.h>
 #endif
 
 #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 "systime.h"
 #include "systty.h"
 
-#include "lisp.h"
 #include "window.h"
 #include "buffer.h"
 #include "charset.h"
 #include "window.h"
 #include "buffer.h"
 #include "charset.h"
@@ -140,7 +151,10 @@ Boston, MA 02110-1301, USA.  */
 Lisp_Object Qprocessp;
 Lisp_Object Qrun, Qstop, Qsignal;
 Lisp_Object Qopen, Qclosed, Qconnect, Qfailed, Qlisten;
 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;
 Lisp_Object QCname, QCbuffer, QChost, QCservice, QCtype;
 Lisp_Object QClocal, QCremote, QCcoding;
 Lisp_Object QCserver, QCnowait, QCnoquery, QCstop;
@@ -187,7 +201,6 @@ extern Lisp_Object QCfilter;
 
 #include "syswait.h"
 
 
 #include "syswait.h"
 
-extern void set_waiting_for_input P_ ((EMACS_TIME *));
 extern char *get_operating_system_release ();
 
 #ifndef USE_CRT_DLL
 extern char *get_operating_system_release ();
 
 #ifndef USE_CRT_DLL
@@ -294,7 +307,10 @@ static Lisp_Object Vprocess_adaptive_read_buffering;
 
 #include "sysselect.h"
 
 
 #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.  */
 
 /* 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.  */
@@ -302,6 +318,12 @@ extern int keyboard_bit_set P_ ((SELECT_TYPE *));
 #define POLL_FOR_INPUT
 #endif
 
 #define POLL_FOR_INPUT
 #endif
 
+static Lisp_Object get_process ();
+static void exec_sentinel ();
+
+extern EMACS_TIME timer_check ();
+extern int timers_run;
+\f
 /* Mask of bits indicating the descriptors that we wait for input on.  */
 
 static SELECT_TYPE input_wait_mask;
 /* Mask of bits indicating the descriptors that we wait for input on.  */
 
 static SELECT_TYPE input_wait_mask;
@@ -370,15 +392,13 @@ struct sockaddr_and_len {
 #define DATAGRAM_CONN_P(proc)  (0)
 #endif
 
 #define DATAGRAM_CONN_P(proc)  (0)
 #endif
 
-static Lisp_Object get_process ();
-static void exec_sentinel ();
-
-extern EMACS_TIME timer_check ();
-extern int timers_run;
-
 /* Maximum number of bytes to send to a pty without an eof.  */
 static int pty_max_bytes;
 
 /* Maximum number of bytes to send to a pty without an eof.  */
 static int pty_max_bytes;
 
+/* Nonzero means don't run process sentinels.  This is used
+   when exiting.  */
+int inhibit_sentinels;
+
 #ifdef HAVE_PTYS
 #ifdef HAVE_PTY_H
 #include <pty.h>
 #ifdef HAVE_PTYS
 #ifdef HAVE_PTY_H
 #include <pty.h>
@@ -391,23 +411,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'.  */
 
 /* 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;
 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->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.  */
 
 }
 
 /*  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;
 {
 status_convert (w)
      WAITTYPE w;
 {
@@ -426,7 +446,7 @@ status_convert (w)
 /* Given a status-list, extract the three pieces of information
    and store them individually through the three pointers.  */
 
 /* 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;
 decode_status (l, symbol, code, coredump)
      Lisp_Object l;
      Lisp_Object *symbol;
@@ -505,7 +525,7 @@ status_message (p)
    The file name of the terminal corresponding to the pty
    is left in the variable pty_name.  */
 
    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;
 allocate_pty ()
 {
   register int c, i;
@@ -590,7 +610,7 @@ allocate_pty ()
 }
 #endif /* HAVE_PTYS */
 \f
 }
 #endif /* HAVE_PTYS */
 \f
-Lisp_Object
+static Lisp_Object
 make_process (name)
      Lisp_Object name;
 {
 make_process (name)
      Lisp_Object name;
 {
@@ -603,11 +623,10 @@ make_process (name)
 
   XSETINT (p->infd, -1);
   XSETINT (p->outfd, -1);
 
   XSETINT (p->infd, -1);
   XSETINT (p->outfd, -1);
-  XSETFASTINT (p->pid, 0);
   XSETFASTINT (p->tick, 0);
   XSETFASTINT (p->update_tick, 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 ();
 
   p->status = Qrun;
   p->mark = Fmake_marker ();
 
@@ -634,7 +653,7 @@ make_process (name)
   return val;
 }
 
   return val;
 }
 
-void
+static void
 remove_process (proc)
      register Lisp_Object proc;
 {
 remove_process (proc)
      register Lisp_Object proc;
 {
@@ -680,6 +699,8 @@ setup_process_coding_systems (process)
       = (struct coding_system *) xmalloc (sizeof (struct coding_system));
   setup_coding_system (p->encode_coding_system,
                       proc_encode_coding_system[outch]);
       = (struct coding_system *) xmalloc (sizeof (struct coding_system));
   setup_coding_system (p->encode_coding_system,
                       proc_encode_coding_system[outch]);
+  if (proc_encode_coding_system[outch]->eol_type == CODING_EOL_UNDECIDED)
+    proc_encode_coding_system[outch]->eol_type = system_eol_type;
 }
 \f
 DEFUN ("processp", Fprocessp, Sprocessp, 1, 1, 0,
 }
 \f
 DEFUN ("processp", Fprocessp, Sprocessp, 1, 1, 0,
@@ -761,6 +782,16 @@ get_process (name)
   return proc;
 }
 
   return proc;
 }
 
+
+#ifdef SIGCHLD
+/* Fdelete_process promises to immediately forget about the process, but in
+   reality, Emacs needs to remember those processes until they have been
+   treated by sigchld_handler; otherwise this handler would consider the
+   process as being synchronous and say that the synchronous process is
+   dead.  */
+static Lisp_Object deleted_pid_list;
+#endif
+
 DEFUN ("delete-process", Fdelete_process, Sdelete_process, 1, 1, 0,
        doc: /* Delete PROCESS: kill it and forget about it immediately.
 PROCESS may be a process, a buffer, the name of a process or buffer, or
 DEFUN ("delete-process", Fdelete_process, Sdelete_process, 1, 1, 0,
        doc: /* Delete PROCESS: kill it and forget about it immediately.
 PROCESS may be a process, a buffer, the name of a process or buffer, or
@@ -768,23 +799,45 @@ nil, indicating the current buffer's process.  */)
      (process)
      register Lisp_Object process;
 {
      (process)
      register Lisp_Object process;
 {
+  register struct Lisp_Process *p;
+
   process = get_process (process);
   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
-       = Fcons (Qsignal, Fcons (make_number (SIGKILL), Qnil));
-      XSETINT (XPROCESS (process)->tick, ++process_tick);
-      status_notify ();
+#ifdef SIGCHLD
+      Lisp_Object symbol;
+
+      /* No problem storing the pid here, as it is still in Vprocess_alist.  */
+      deleted_pid_list = Fcons (make_fixnum_or_float (p->pid),
+                               /* GC treated elements set to nil.  */
+                               Fdelq (Qnil, deleted_pid_list));
+      /* If the process has already signaled, remove it from the list.  */
+      if (p->raw_status_new)
+       update_status (p);
+      symbol = p->status;
+      if (CONSP (p->status))
+       symbol = XCAR (p->status);
+      if (EQ (symbol, Qsignal) || EQ (symbol, Qexit))
+       Fdelete (make_fixnum_or_float (p->pid), deleted_pid_list);
+      else
+#endif
+       {
+         Fkill_process (process, Qnil);
+         /* Do this now, since remove_process will make sigchld_handler do nothing.  */
+         p->status
+           = Fcons (Qsignal, Fcons (make_number (SIGKILL), Qnil));
+         XSETINT (p->tick, ++process_tick);
+         status_notify (p);
+       }
     }
   remove_process (process);
   return Qnil;
     }
   remove_process (process);
   return Qnil;
@@ -820,7 +873,7 @@ nil, indicating the current buffer's process.  */)
     return process;
 
   p = XPROCESS (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))
     update_status (p);
   status = p->status;
   if (CONSP (status))
@@ -845,7 +898,7 @@ If PROCESS has not yet exited or died, return 0.  */)
      register Lisp_Object process;
 {
   CHECK_PROCESS (process);
      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));
     update_status (XPROCESS (process));
   if (CONSP (XPROCESS (process)->status))
     return XCAR (XCDR (XPROCESS (process)->status));
@@ -860,7 +913,9 @@ For a network connection, this value is nil.  */)
      register Lisp_Object process;
 {
   CHECK_PROCESS (process);
      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,
 }
 
 DEFUN ("process-name", Fprocess_name, Sprocess_name, 1, 1, 0,
@@ -1189,9 +1244,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.
 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
 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;
 {
      (address, omit_port)
      Lisp_Object address, omit_port;
 {
@@ -1201,13 +1258,13 @@ IP address.  Returns nil if format of ADDRESS is invalid.  */)
   if (STRINGP (address))  /* AF_LOCAL */
     return address;
 
   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;
 
     {
       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;
        {
          args[0] = build_string ("%d.%d.%d.%d");
          nargs = 4;
@@ -1217,6 +1274,16 @@ IP address.  Returns nil if format of ADDRESS is invalid.  */)
          args[0] = build_string ("%d.%d.%d.%d:%d");
          nargs = 5;
        }
          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;
 
       else
        return Qnil;
 
@@ -1238,7 +1305,7 @@ IP address.  Returns nil if format of ADDRESS is invalid.  */)
 }
 #endif
 \f
 }
 #endif
 \f
-Lisp_Object
+static Lisp_Object
 list_processes_1 (query_only)
      Lisp_Object query_only;
 {
 list_processes_1 (query_only)
      Lisp_Object query_only;
 {
@@ -1247,6 +1314,7 @@ list_processes_1 (query_only)
   register struct Lisp_Process *p;
   char tembuf[300];
   int w_proc, w_buffer, w_tty;
   register struct Lisp_Process *p;
   char tembuf[300];
   int w_proc, w_buffer, w_tty;
+  int exited = 0;
   Lisp_Object i_status, i_buffer, i_tty, i_command;
 
   w_proc = 4;    /* Proc   */
   Lisp_Object i_status, i_buffer, i_tty, i_command;
 
   w_proc = 4;    /* Proc   */
@@ -1330,7 +1398,7 @@ list_processes_1 (query_only)
       Finsert (1, &p->name);
       Findent_to (i_status, minspace);
 
       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))
        update_status (p);
       symbol = p->status;
       if (CONSP (p->status))
@@ -1373,8 +1441,8 @@ list_processes_1 (query_only)
            }
        }
 
            }
        }
 
-      if (EQ (symbol, Qsignal) || EQ (symbol, Qexit))
-       remove_process (proc);
+      if (EQ (symbol, Qsignal) || EQ (symbol, Qexit) || EQ (symbol, Qclosed))
+       exited++;
 
       Findent_to (i_buffer, minspace);
       if (NILP (p->buffer))
 
       Findent_to (i_buffer, minspace);
       if (NILP (p->buffer))
@@ -1438,6 +1506,8 @@ list_processes_1 (query_only)
          insert_string ("\n");
        }
     }
          insert_string ("\n");
        }
     }
+  if (exited)
+    status_notify (NULL);
   return Qnil;
 }
 
   return Qnil;
 }
 
@@ -1550,7 +1620,7 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS)  */)
 #endif
 
   /* Make the process marker point into the process buffer (if any).  */
 #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)));
     set_marker_both (XPROCESS (proc)->mark, buffer,
                     BUF_ZV (XBUFFER (buffer)),
                     BUF_ZV_BYTE (XBUFFER (buffer)));
@@ -1702,13 +1772,13 @@ start_process_unwind (proc)
     abort ();
 
   /* Was PROC started successfully?  */
     abort ();
 
   /* Was PROC started successfully?  */
-  if (XINT (XPROCESS (proc)->pid) <= 0)
+  if (XPROCESS (proc)->pid <= 0)
     remove_process (proc);
 
   return Qnil;
 }
 
     remove_process (proc);
 
   return Qnil;
 }
 
-void
+static void
 create_process_1 (timer)
      struct atimer *timer;
 {
 create_process_1 (timer)
      struct atimer *timer;
 {
@@ -1786,6 +1856,12 @@ create_process (process, new_argv, current_dir)
 #endif
       if (forkin < 0)
        report_file_error ("Opening pty", Qnil);
 #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 */
 #else
       forkin = forkout = -1;
 #endif /* not USG, or USG_SUBTTY_WORKS */
@@ -1907,7 +1983,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.  */
      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;
 
 
   BLOCK_INPUT;
 
@@ -2070,8 +2146,10 @@ create_process (process, new_argv, current_dir)
 #endif /* SIGCHLD */
 #endif /* !POSIX_SIGNALS */
 
 #endif /* SIGCHLD */
 #endif /* !POSIX_SIGNALS */
 
+#if !defined (RTU) && !defined (UNIPLUS) && !defined (DONT_REOPEN_PTY)
        if (pty_flag)
          child_setup_tty (xforkout);
        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);
 #ifdef WINDOWSNT
        pid = child_setup (xforkin, xforkout, xforkout,
                           new_argv, 1, current_dir);
@@ -2096,7 +2174,7 @@ create_process (process, new_argv, current_dir)
   else
     {
       /* vfork succeeded.  */
   else
     {
       /* vfork succeeded.  */
-      XSETFASTINT (XPROCESS (process)->pid, pid);
+      XPROCESS (process)->pid = pid;
 
 #ifdef WINDOWSNT
       register_child (pid, inchannel);
 
 #ifdef WINDOWSNT
       register_child (pid, inchannel);
@@ -2198,6 +2276,20 @@ conv_sockaddr_to_lisp (sa, len)
        cp = (unsigned char *)&sin->sin_addr;
        break;
       }
        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:
       {
 #ifdef HAVE_LOCAL_SOCKETS
     case AF_LOCAL:
       {
@@ -2242,6 +2334,13 @@ get_lisp_to_sockaddr_size (address, familyp)
          *familyp = AF_INET;
          return sizeof (struct sockaddr_in);
        }
          *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))
     }
 #ifdef HAVE_LOCAL_SOCKETS
   else if (STRINGP (address))
@@ -2261,7 +2360,11 @@ get_lisp_to_sockaddr_size (address, familyp)
 }
 
 /* Convert an address object (vector or string) to an internal sockaddr.
 }
 
 /* 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)
 
 static void
 conv_lisp_to_sockaddr (family, address, sa, len)
@@ -2275,7 +2378,6 @@ conv_lisp_to_sockaddr (family, address, sa, len)
   register int i;
 
   bzero (sa, len);
   register int i;
 
   bzero (sa, len);
-  sa->sa_family = family;
 
   if (VECTORP (address))
     {
 
   if (VECTORP (address))
     {
@@ -2287,7 +2389,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;
          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))
     {
     }
   else if (STRINGP (address))
     {
@@ -2298,6 +2419,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++;
          cp = SDATA (address);
          for (i = 0; i < sizeof (sockun->sun_path) && *cp; i++)
            sockun->sun_path[i] = *cp++;
+         sa->sa_family = family;
        }
 #endif
       return;
        }
 #endif
       return;
@@ -2531,7 +2653,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.  */
 
 \f
 /* A version of request_sigio suitable for a record_unwind_protect.  */
 
-Lisp_Object
+static Lisp_Object
 unwind_request_sigio (dummy)
      Lisp_Object dummy;
 {
 unwind_request_sigio (dummy)
      Lisp_Object dummy;
 {
@@ -2581,10 +2703,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
 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.
   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
 
 :local ADDRESS -- ADDRESS is the local address used for the connection.
 This parameter is ignored when opening a client process. When specified
@@ -2701,8 +2826,8 @@ usage: (make-network-process &rest ARGS)  */)
   struct Lisp_Process *p;
 #ifdef HAVE_GETADDRINFO
   struct addrinfo ai, *res, *lres;
   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
   {
 #else /* HAVE_GETADDRINFO */
   struct _emacs_addrinfo
   {
@@ -2841,19 +2966,29 @@ usage: (make-network-process &rest ARGS)  */)
 
   /* :family FAMILY -- nil (for Inet), local, or integer.  */
   tem = Fplist_get (contact, QCfamily);
 
   /* :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
     }
 #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");
     error ("Unknown address family");
+
   ai.ai_family = family;
 
   /* :service SERVICE -- string, integer (port number), or t (random port).  */
   ai.ai_family = family;
 
   /* :service SERVICE -- string, integer (port number), or t (random port).  */
@@ -2919,7 +3054,7 @@ usage: (make-network-process &rest ARGS)  */)
       QUIT;
       memset (&hints, 0, sizeof (hints));
       hints.ai_flags = 0;
       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);
       hints.ai_socktype = socktype;
       hints.ai_protocol = 0;
       ret = getaddrinfo (SDATA (host), portstring, &hints, &res);
@@ -3258,12 +3393,18 @@ usage: (make-network-process &rest ARGS)  */)
     p->kill_without_query = Qt;
   if ((tem = Fplist_get (contact, QCstop), !NILP (tem)))
     p->command = Qt;
     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;
 
   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)
     {
 #ifdef NON_BLOCKING_CONNECT
   if (is_non_blocking_client)
     {
@@ -3507,6 +3648,21 @@ static struct ifflag_def ifflag_table[] = {
 #endif
 #ifdef IFF_DYNAMIC
   { IFF_DYNAMIC,       "dynamic" },
 #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 }
 };
 #endif
   { 0, 0 }
 };
@@ -3544,7 +3700,7 @@ FLAGS is the current flags of the interface.  */)
       int fnum;
 
       any++;
       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)
            {
        {
          if (flags & fp->flag_bit)
            {
@@ -3580,11 +3736,15 @@ FLAGS is the current flags of the interface.  */)
   res = Fcons (elt, res);
 
   elt = Qnil;
   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++;
   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));
       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);
     }
 #endif
   res = Fcons (elt, res);
@@ -3722,62 +3882,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.
 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.  */)
 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 (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;
-
-       XSETINT (timeout, XINT (timeout) + carry);
-       useconds -= carry * 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);
 
 
-       /* 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;
-         }
-      }
-    }
-  else
-    useconds = 0;
+      if (INTEGERP (millisec))
+       {
+         int carry;
+         usecs += XINT (millisec) * 1000;
+         carry = usecs / 1000000;
+         secs += carry;
+         if ((usecs -= carry * 1000000) < 0)
+           {
+             secs--;
+             usecs += 1000000;
+           }
+       }
 
 
-  if (! NILP (timeout))
-    {
-      CHECK_NUMBER (timeout);
-      seconds = XINT (timeout);
-      if (seconds < 0 || (seconds == 0 && useconds == 0))
-       seconds = -1;
+      if (secs < 0 || (secs == 0 && usecs == 0))
+       secs = -1, usecs = 0;
     }
   else
     }
   else
-    seconds = NILP (process) ? -1 : 0;
+    secs = NILP (process) ? -1 : 0;
 
   return
 
   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 :
                                  Qnil,
                                  !NILP (process) ? XPROCESS (process) : NULL,
                                  NILP (just_this_one) ? 0 :
@@ -3802,6 +3960,9 @@ server_accept_connection (server, channel)
   union u_sockaddr {
     struct sockaddr sa;
     struct sockaddr_in in;
   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
 #ifdef HAVE_LOCAL_SOCKETS
     struct sockaddr_un un;
 #endif
@@ -3858,6 +4019,26 @@ server_accept_connection (server, channel)
       }
       break;
 
       }
       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
 #ifdef HAVE_LOCAL_SOCKETS
     case AF_LOCAL:
 #endif
@@ -3928,7 +4109,7 @@ server_accept_connection (server, channel)
   p->sentinel = ps->sentinel;
   p->filter = ps->filter;
   p->command = Qnil;
   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;
   XSETINT (p->infd, s);
   XSETINT (p->outfd, s);
   p->status = Qrun;
@@ -3984,12 +4165,39 @@ server_accept_connection (server, channel)
    when not inside wait_reading_process_output.  */
 static int waiting_for_user_input_p;
 
    when not inside wait_reading_process_output.  */
 static int waiting_for_user_input_p;
 
+static Lisp_Object
+wait_reading_process_output_unwind (data)
+     Lisp_Object data;
+{
+  waiting_for_user_input_p = XINT (data);
+  return Qnil;
+}
+
 /* This is here so breakpoints can be put on it.  */
 static void
 wait_reading_process_output_1 ()
 {
 }
 
 /* This is here so breakpoints can be put on it.  */
 static void
 wait_reading_process_output_1 ()
 {
 }
 
+/* Use a wrapper around select to work around a bug in gdb 5.3.
+   Normally, the wrapper is optimzed away by inlining.
+
+   If emacs is stopped inside select, the gdb backtrace doesn't
+   show the function which called select, so it is practically
+   impossible to step through wait_reading_process_output.  */
+
+#ifndef select
+static INLINE int
+select_wrapper (n, rfd, wfd, xfd, tmo)
+  int n;
+  SELECT_TYPE *rfd, *wfd, *xfd;
+  EMACS_TIME *tmo;
+{
+  return select (n, rfd, wfd, xfd, tmo);
+}
+#define select select_wrapper
+#endif
+
 /* Read and dispose of subprocess output while waiting for timeout to
    elapse and/or keyboard input to be available.
 
 /* Read and dispose of subprocess output while waiting for timeout to
    elapse and/or keyboard input to be available.
 
@@ -4047,9 +4255,7 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
   EMACS_TIME timeout, end_time;
   int wait_channel = -1;
   int got_some_input = 0;
   EMACS_TIME timeout, end_time;
   int wait_channel = -1;
   int got_some_input = 0;
-  /* Either nil or a cons cell, the car of which is of interest and
-     may be changed outside of this routine.  */
-  int saved_waiting_for_user_input_p = waiting_for_user_input_p;
+  int count = SPECPDL_INDEX ();
 
   FD_ZERO (&Available);
 #ifdef NON_BLOCKING_CONNECT
 
   FD_ZERO (&Available);
 #ifdef NON_BLOCKING_CONNECT
@@ -4060,6 +4266,8 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
   if (wait_proc != NULL)
     wait_channel = XINT (wait_proc->infd);
 
   if (wait_proc != NULL)
     wait_channel = XINT (wait_proc->infd);
 
+  record_unwind_protect (wait_reading_process_output_unwind,
+                        make_number (waiting_for_user_input_p));
   waiting_for_user_input_p = read_kbd;
 
   /* Since we may need to wait several times,
   waiting_for_user_input_p = read_kbd;
 
   /* Since we may need to wait several times,
@@ -4222,15 +4430,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 ();
              /* 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.  */
            }
        }
 
       /* 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);
        update_status (wait_proc);
-      if (wait_proc != 0
+      if (wait_proc
          && ! EQ (wait_proc->status, Qrun)
          && ! EQ (wait_proc->status, Qconnect))
        {
          && ! EQ (wait_proc->status, Qrun)
          && ! EQ (wait_proc->status, Qconnect))
        {
@@ -4614,7 +4822,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);
                  /* 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
                    update_status (XPROCESS (proc));
                  if (EQ (XPROCESS (proc)->status, Qrun))
                    XPROCESS (proc)->status
@@ -4686,7 +4894,7 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
        }                       /* end for each file descriptor */
     }                          /* end while exit conditions not met */
 
        }                       /* end for each file descriptor */
     }                          /* end while exit conditions not met */
 
-  waiting_for_user_input_p = saved_waiting_for_user_input_p;
+  unbind_to (count, Qnil);
 
   /* If calling from keyboard input, do not quit
      since we want to return C-g as an input character.
 
   /* If calling from keyboard input, do not quit
      since we want to return C-g as an input character.
@@ -4740,7 +4948,7 @@ read_process_output_error_handler (error)
    The characters read are decoded according to PROC's coding-system
    for decoding.  */
 
    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;
 read_process_output (proc, channel)
      Lisp_Object proc;
      register int channel;
@@ -4923,6 +5131,10 @@ read_process_output (proc, channel)
              p->encode_coding_system = coding->symbol;
              setup_coding_system (coding->symbol,
                                   proc_encode_coding_system[XINT (p->outfd)]);
              p->encode_coding_system = coding->symbol;
              setup_coding_system (coding->symbol,
                                   proc_encode_coding_system[XINT (p->outfd)]);
+             if (proc_encode_coding_system[XINT (p->outfd)]->eol_type
+                 == CODING_EOL_UNDECIDED)
+               proc_encode_coding_system[XINT (p->outfd)]->eol_type
+                 = system_eol_type;
            }
        }
 
            }
        }
 
@@ -4963,7 +5175,7 @@ read_process_output (proc, channel)
 #endif
        /* But do it only if the caller is actually going to read events.
           Otherwise there's no need to make him wake up, and it could
 #endif
        /* But do it only if the caller is actually going to read events.
           Otherwise there's no need to make him wake up, and it could
-          cause trouble (for example it would make Fsit_for return).  */
+          cause trouble (for example it would make sit_for return).  */
        if (waiting_for_user_input_p == -1)
          record_asynch_buffer_change ();
 
        if (waiting_for_user_input_p == -1)
          record_asynch_buffer_change ();
 
@@ -5030,6 +5242,10 @@ read_process_output (proc, channel)
              p->encode_coding_system = coding->symbol;
              setup_coding_system (coding->symbol,
                                   proc_encode_coding_system[XINT (p->outfd)]);
              p->encode_coding_system = coding->symbol;
              setup_coding_system (coding->symbol,
                                   proc_encode_coding_system[XINT (p->outfd)]);
+             if (proc_encode_coding_system[XINT (p->outfd)]->eol_type
+                 == CODING_EOL_UNDECIDED)
+               proc_encode_coding_system[XINT (p->outfd)]->eol_type
+                 = system_eol_type;
            }
        }
       carryover = nbytes - coding->consumed;
            }
        }
       carryover = nbytes - coding->consumed;
@@ -5131,7 +5347,7 @@ send_process_trap ()
 
    This function can evaluate Lisp code and can garbage collect.  */
 
 
    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;
 send_process (proc, buf, len, object)
      volatile Lisp_Object proc;
      unsigned char *volatile buf;
@@ -5151,7 +5367,7 @@ send_process (proc, buf, len, object)
   VMS_PROC_STUFF *vs, *get_vms_process_pointer();
 #endif /* VMS */
 
   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));
     update_status (p);
   if (! EQ (p->status, Qrun))
     error ("Process %s not running", SDATA (p->name));
@@ -5172,6 +5388,8 @@ send_process (proc, buf, len, object)
           sending a multibyte text, thus we must encode it by the
           original coding system specified for the current process.  */
        setup_coding_system (p->encode_coding_system, coding);
           sending a multibyte text, thus we must encode it by the
           original coding system specified for the current process.  */
        setup_coding_system (p->encode_coding_system, coding);
+      if (coding->eol_type == CODING_EOL_UNDECIDED)
+       coding->eol_type = system_eol_type;
       /* src_multibyte should be set to 1 _after_ a call to
         setup_coding_system, since it resets src_multibyte to
         zero.  */
       /* src_multibyte should be set to 1 _after_ a call to
         setup_coding_system, since it resets src_multibyte to
         zero.  */
@@ -5415,8 +5633,7 @@ send_process (proc, buf, len, object)
       proc = process_sent_to;
       p = XPROCESS (proc);
 #endif
       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);
       p->status = Fcons (Qexit, Fcons (make_number (256), Qnil));
       XSETINT (p->tick, ++process_tick);
       deactivate_process (proc);
@@ -5531,7 +5748,7 @@ return t unconditionally.  */)
 
   gid = emacs_get_tty_pgrp (p);
 
 
   gid = emacs_get_tty_pgrp (p);
 
-  if (gid == XFASTINT (p->pid))
+  if (gid == p->pid)
     return Qnil;
   return Qt;
 }
     return Qnil;
   return Qt;
 }
@@ -5578,7 +5795,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.  */
   /* 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
   else
     {
 #ifdef SIGNALS_VIA_CHARACTERS
@@ -5697,7 +5914,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.  */
       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.
 
       /* 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.
@@ -5707,12 +5924,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.  */
 #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.  */
 #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;
     }
 
        return;
     }
 
@@ -5720,12 +5937,11 @@ process_send_signal (process, signo, current_group, nomsg)
     {
 #ifdef SIGCONT
     case SIGCONT:
     {
 #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)
       p->status = Qrun;
       XSETINT (p->tick, ++process_tick);
       if (!nomsg)
-       status_notify ();
+       status_notify (NULL);
       break;
 #endif /* ! defined (SIGCONT) */
     case SIGINT:
       break;
 #endif /* ! defined (SIGCONT) */
     case SIGINT:
@@ -5740,7 +5956,7 @@ process_send_signal (process, signo, current_group, nomsg)
 #endif
     case SIGKILL:
 #ifdef VMS
 #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));
       whoosh:
 #endif
       flush_pending_output (XINT (p->infd));
@@ -5752,7 +5968,7 @@ process_send_signal (process, signo, current_group, nomsg)
      obvious alternative.  */
   if (no_pgrp)
     {
      obvious alternative.  */
   if (no_pgrp)
     {
-      kill (XFASTINT (p->pid), signo);
+      kill (p->pid, signo);
       return;
     }
 
       return;
     }
 
@@ -5765,7 +5981,7 @@ process_send_signal (process, signo, current_group, nomsg)
     }
   else
     {
     }
   else
     {
-      gid = - XFASTINT (p->pid);
+      gid = - p->pid;
       kill (gid, signo);
     }
 #else /* ! defined (TIOCSIGSEND) */
       kill (gid, signo);
     }
 #else /* ! defined (TIOCSIGSEND) */
@@ -5885,11 +6101,17 @@ SIGCODE may be an integer, or a symbol whose name is a signal name.  */)
      (process, sigcode)
      Lisp_Object process, sigcode;
 {
      (process, sigcode)
      Lisp_Object process, sigcode;
 {
-  Lisp_Object pid;
+  pid_t pid;
 
   if (INTEGERP (process))
     {
 
   if (INTEGERP (process))
     {
-      pid = process;
+      pid = XINT (process);
+      goto got_it;
+    }
+
+  if (FLOATP (process))
+    {
+      pid = (pid_t) XFLOAT (process);
       goto got_it;
     }
 
       goto got_it;
     }
 
@@ -5898,8 +6120,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))
        {
       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;
            goto got_it;
        }
       process = tem;
@@ -5912,7 +6134,7 @@ SIGCODE may be an integer, or a symbol whose name is a signal name.  */)
 
   CHECK_PROCESS (process);
   pid = XPROCESS (process)->pid;
 
   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:
     error ("Cannot signal process %s", SDATA (XPROCESS (process)->name));
 
  got_it:
@@ -5930,97 +6152,100 @@ SIGCODE may be an integer, or a symbol whose name is a signal name.  */)
       CHECK_SYMBOL (sigcode);
       name = SDATA (SYMBOL_NAME (sigcode));
 
       CHECK_SYMBOL (sigcode);
       name = SDATA (SYMBOL_NAME (sigcode));
 
+      if (!strncmp(name, "SIG", 3))
+       name += 3;
+
       if (0)
        ;
 #ifdef SIGHUP
       if (0)
        ;
 #ifdef SIGHUP
-      handle_signal ("SIGHUP", SIGHUP);
+      handle_signal ("HUP", SIGHUP);
 #endif
 #ifdef SIGINT
 #endif
 #ifdef SIGINT
-      handle_signal ("SIGINT", SIGINT);
+      handle_signal ("INT", SIGINT);
 #endif
 #ifdef SIGQUIT
 #endif
 #ifdef SIGQUIT
-      handle_signal ("SIGQUIT", SIGQUIT);
+      handle_signal ("QUIT", SIGQUIT);
 #endif
 #ifdef SIGILL
 #endif
 #ifdef SIGILL
-      handle_signal ("SIGILL", SIGILL);
+      handle_signal ("ILL", SIGILL);
 #endif
 #ifdef SIGABRT
 #endif
 #ifdef SIGABRT
-      handle_signal ("SIGABRT", SIGABRT);
+      handle_signal ("ABRT", SIGABRT);
 #endif
 #ifdef SIGEMT
 #endif
 #ifdef SIGEMT
-      handle_signal ("SIGEMT", SIGEMT);
+      handle_signal ("EMT", SIGEMT);
 #endif
 #ifdef SIGKILL
 #endif
 #ifdef SIGKILL
-      handle_signal ("SIGKILL", SIGKILL);
+      handle_signal ("KILL", SIGKILL);
 #endif
 #ifdef SIGFPE
 #endif
 #ifdef SIGFPE
-      handle_signal ("SIGFPE", SIGFPE);
+      handle_signal ("FPE", SIGFPE);
 #endif
 #ifdef SIGBUS
 #endif
 #ifdef SIGBUS
-      handle_signal ("SIGBUS", SIGBUS);
+      handle_signal ("BUS", SIGBUS);
 #endif
 #ifdef SIGSEGV
 #endif
 #ifdef SIGSEGV
-      handle_signal ("SIGSEGV", SIGSEGV);
+      handle_signal ("SEGV", SIGSEGV);
 #endif
 #ifdef SIGSYS
 #endif
 #ifdef SIGSYS
-      handle_signal ("SIGSYS", SIGSYS);
+      handle_signal ("SYS", SIGSYS);
 #endif
 #ifdef SIGPIPE
 #endif
 #ifdef SIGPIPE
-      handle_signal ("SIGPIPE", SIGPIPE);
+      handle_signal ("PIPE", SIGPIPE);
 #endif
 #ifdef SIGALRM
 #endif
 #ifdef SIGALRM
-      handle_signal ("SIGALRM", SIGALRM);
+      handle_signal ("ALRM", SIGALRM);
 #endif
 #ifdef SIGTERM
 #endif
 #ifdef SIGTERM
-      handle_signal ("SIGTERM", SIGTERM);
+      handle_signal ("TERM", SIGTERM);
 #endif
 #ifdef SIGURG
 #endif
 #ifdef SIGURG
-      handle_signal ("SIGURG", SIGURG);
+      handle_signal ("URG", SIGURG);
 #endif
 #ifdef SIGSTOP
 #endif
 #ifdef SIGSTOP
-      handle_signal ("SIGSTOP", SIGSTOP);
+      handle_signal ("STOP", SIGSTOP);
 #endif
 #ifdef SIGTSTP
 #endif
 #ifdef SIGTSTP
-      handle_signal ("SIGTSTP", SIGTSTP);
+      handle_signal ("TSTP", SIGTSTP);
 #endif
 #ifdef SIGCONT
 #endif
 #ifdef SIGCONT
-      handle_signal ("SIGCONT", SIGCONT);
+      handle_signal ("CONT", SIGCONT);
 #endif
 #ifdef SIGCHLD
 #endif
 #ifdef SIGCHLD
-      handle_signal ("SIGCHLD", SIGCHLD);
+      handle_signal ("CHLD", SIGCHLD);
 #endif
 #ifdef SIGTTIN
 #endif
 #ifdef SIGTTIN
-      handle_signal ("SIGTTIN", SIGTTIN);
+      handle_signal ("TTIN", SIGTTIN);
 #endif
 #ifdef SIGTTOU
 #endif
 #ifdef SIGTTOU
-      handle_signal ("SIGTTOU", SIGTTOU);
+      handle_signal ("TTOU", SIGTTOU);
 #endif
 #ifdef SIGIO
 #endif
 #ifdef SIGIO
-      handle_signal ("SIGIO", SIGIO);
+      handle_signal ("IO", SIGIO);
 #endif
 #ifdef SIGXCPU
 #endif
 #ifdef SIGXCPU
-      handle_signal ("SIGXCPU", SIGXCPU);
+      handle_signal ("XCPU", SIGXCPU);
 #endif
 #ifdef SIGXFSZ
 #endif
 #ifdef SIGXFSZ
-      handle_signal ("SIGXFSZ", SIGXFSZ);
+      handle_signal ("XFSZ", SIGXFSZ);
 #endif
 #ifdef SIGVTALRM
 #endif
 #ifdef SIGVTALRM
-      handle_signal ("SIGVTALRM", SIGVTALRM);
+      handle_signal ("VTALRM", SIGVTALRM);
 #endif
 #ifdef SIGPROF
 #endif
 #ifdef SIGPROF
-      handle_signal ("SIGPROF", SIGPROF);
+      handle_signal ("PROF", SIGPROF);
 #endif
 #ifdef SIGWINCH
 #endif
 #ifdef SIGWINCH
-      handle_signal ("SIGWINCH", SIGWINCH);
+      handle_signal ("WINCH", SIGWINCH);
 #endif
 #ifdef SIGINFO
 #endif
 #ifdef SIGINFO
-      handle_signal ("SIGINFO", SIGINFO);
+      handle_signal ("INFO", SIGINFO);
 #endif
 #ifdef SIGUSR1
 #endif
 #ifdef SIGUSR1
-      handle_signal ("SIGUSR1", SIGUSR1);
+      handle_signal ("USR1", SIGUSR1);
 #endif
 #ifdef SIGUSR2
 #endif
 #ifdef SIGUSR2
-      handle_signal ("SIGUSR2", SIGUSR2);
+      handle_signal ("USR2", SIGUSR2);
 #endif
       else
        error ("Undefined signal name %s", name);
 #endif
       else
        error ("Undefined signal name %s", name);
@@ -6028,7 +6253,7 @@ SIGCODE may be an integer, or a symbol whose name is a signal name.  */)
 
 #undef handle_signal
 
 
 #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,
 }
 
 DEFUN ("process-send-eof", Fprocess_send_eof, Sprocess_send_eof, 0, 1, 0,
@@ -6052,7 +6277,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.  */
   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));
     update_status (XPROCESS (proc));
   if (! EQ (XPROCESS (proc)->status, Qrun))
     error ("Process %s not running", SDATA (XPROCESS (proc)->name));
@@ -6077,7 +6302,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.)  */
         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.  */
          || 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.  */
@@ -6087,6 +6312,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);
       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])
       old_outfd = XINT (XPROCESS (proc)->outfd);
 
       if (!proc_encode_coding_system[new_outfd])
@@ -6152,6 +6379,7 @@ kill_buffer_processes (buffer)
    ** Malloc WARNING: This should never call malloc either directly or
    indirectly; if it does, that is a bug  */
 
    ** Malloc WARNING: This should never call malloc either directly or
    indirectly; if it does, that is a bug  */
 
+#ifdef SIGCHLD
 SIGTYPE
 sigchld_handler (signo)
      int signo;
 SIGTYPE
 sigchld_handler (signo)
      int signo;
@@ -6209,12 +6437,21 @@ sigchld_handler (signo)
 
       /* Find the process that signaled us, and record its status.  */
 
 
       /* Find the process that signaled us, and record its status.  */
 
+      /* The process can have been deleted by Fdelete_process.  */
+      tail = Fmember (make_fixnum_or_float (pid), deleted_pid_list);
+      if (!NILP (tail))
+       {
+         Fsetcar (tail, Qnil);
+         goto sigchld_end_of_loop;
+       }
+
+      /* Otherwise, if it is asynchronous, it is in Vprocess_alist.  */
       p = 0;
       for (tail = Vprocess_alist; GC_CONSP (tail); tail = XCDR (tail))
        {
          proc = XCDR (XCAR (tail));
          p = XPROCESS (proc);
       p = 0;
       for (tail = Vprocess_alist; GC_CONSP (tail); tail = XCDR (tail))
        {
          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;
        }
            break;
          p = 0;
        }
@@ -6226,7 +6463,7 @@ sigchld_handler (signo)
          {
            proc = XCDR (XCAR (tail));
            p = XPROCESS (proc);
          {
            proc = XCDR (XCAR (tail));
            p = XPROCESS (proc);
-           if (GC_INTEGERP (p->pid) && XINT (p->pid) == -1)
+           if (p->pid == -1)
              break;
            p = 0;
          }
              break;
            p = 0;
          }
@@ -6239,8 +6476,8 @@ sigchld_handler (signo)
 
          XSETINT (p->tick, ++process_tick);
          u.wt = w;
 
          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))
 
          /* If process has terminated, stop waiting for its output.  */
          if ((WIFSIGNALED (w) || WIFEXITED (w))
@@ -6260,8 +6497,8 @@ sigchld_handler (signo)
            EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
        }
 
            EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
        }
 
-       /* There was no asynchronous process found for that id.  Check
-          if we have a synchronous process.  */
+      /* There was no asynchronous process found for that pid: we have
+        a synchronous process.  */
       else
        {
          synch_process_alive = 0;
       else
        {
          synch_process_alive = 0;
@@ -6278,6 +6515,9 @@ sigchld_handler (signo)
            EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
        }
 
            EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
        }
 
+    sigchld_end_of_loop:
+      ;
+
       /* On some systems, we must return right away.
         If any more processes want to signal us, we will
         get another signal.
       /* On some systems, we must return right away.
         If any more processes want to signal us, we will
         get another signal.
@@ -6294,6 +6534,7 @@ sigchld_handler (signo)
 #endif /* USG, but not HPUX with WNOHANG */
     }
 }
 #endif /* USG, but not HPUX with WNOHANG */
     }
 }
+#endif /* SIGCHLD */
 \f
 
 static Lisp_Object
 \f
 
 static Lisp_Object
@@ -6325,6 +6566,9 @@ exec_sentinel (proc, reason)
   int outer_running_asynch_code = running_asynch_code;
   int waiting = waiting_for_user_input_p;
 
   int outer_running_asynch_code = running_asynch_code;
   int waiting = waiting_for_user_input_p;
 
+  if (inhibit_sentinels)
+    return;
+
   /* No need to gcpro these, because all we do with them later
      is test them for EQness, and none of them should be a string.  */
   odeactivate = Vdeactivate_mark;
   /* No need to gcpro these, because all we do with them later
      is test them for EQness, and none of them should be a string.  */
   odeactivate = Vdeactivate_mark;
@@ -6381,7 +6625,7 @@ exec_sentinel (proc, reason)
 #endif
     /* But do it only if the caller is actually going to read events.
        Otherwise there's no need to make him wake up, and it could
 #endif
     /* But do it only if the caller is actually going to read events.
        Otherwise there's no need to make him wake up, and it could
-       cause trouble (for example it would make Fsit_for return).  */
+       cause trouble (for example it would make sit_for return).  */
     if (waiting_for_user_input_p == -1)
       record_asynch_buffer_change ();
 
     if (waiting_for_user_input_p == -1)
       record_asynch_buffer_change ();
 
@@ -6393,8 +6637,9 @@ exec_sentinel (proc, reason)
    This is usually done while Emacs is waiting for keyboard input
    but can be done at other times.  */
 
    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;
 {
   register Lisp_Object proc, buffer;
   Lisp_Object tail, msg;
@@ -6430,12 +6675,13 @@ status_notify ()
                 && ! EQ (p->status, Qlisten)
                 && ! EQ (p->command, Qt)  /* Network process not stopped.  */
                 && XINT (p->infd) >= 0
                 && ! 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.  */
                 && 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);
 
            update_status (p);
          msg = status_message (p);
 
@@ -6633,7 +6879,7 @@ delete_keyboard_wait_descriptor (desc)
 /* Return nonzero if *MASK has a bit set
    that corresponds to one of the keyboard input descriptors.  */
 
 /* 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;
 {
 keyboard_bit_set (mask)
      SELECT_TYPE *mask;
 {
@@ -6652,6 +6898,8 @@ init_process ()
 {
   register int i;
 
 {
   register int i;
 
+  inhibit_sentinels = 0;
+
 #ifdef SIGCHLD
 #ifndef CANNOT_DUMP
   if (! noninteractive || initialized)
 #ifdef SIGCHLD
 #ifndef CANNOT_DUMP
   if (! noninteractive || initialized)
@@ -6677,6 +6925,9 @@ init_process ()
   FD_SET (0, &input_wait_mask);
 
   Vprocess_alist = Qnil;
   FD_SET (0, &input_wait_mask);
 
   Vprocess_alist = Qnil;
+#ifdef SIGCHLD
+  deleted_pid_list = Qnil;
+#endif
   for (i = 0; i < MAXDESC; i++)
     {
       chan_process[i] = Qnil;
   for (i = 0; i < MAXDESC; i++)
     {
       chan_process[i] = Qnil;
@@ -6704,6 +6955,10 @@ init_process ()
 #endif
 #ifdef HAVE_LOCAL_SOCKETS
    ADD_SUBFEATURE (QCfamily, Qlocal);
 #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);
 #endif
 #ifdef HAVE_GETSOCKNAME
    ADD_SUBFEATURE (QCservice, Qt);
@@ -6763,6 +7018,12 @@ syms_of_process ()
   staticpro (&Qlisten);
   Qlocal = intern ("local");
   staticpro (&Qlocal);
   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);
 
   Qdatagram = intern ("datagram");
   staticpro (&Qdatagram);
 
@@ -6805,6 +7066,9 @@ syms_of_process ()
   staticpro (&Qlast_nonmenu_event);
 
   staticpro (&Vprocess_alist);
   staticpro (&Qlast_nonmenu_event);
 
   staticpro (&Vprocess_alist);
+#ifdef SIGCHLD
+  staticpro (&deleted_pid_list);
+#endif
 
   DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes,
               doc: /* *Non-nil means delete processes immediately when they exit.
 
   DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes,
               doc: /* *Non-nil means delete processes immediately when they exit.
@@ -6827,7 +7091,7 @@ 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 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
 is read in very small blocks, potentially resulting in very poor performance.
 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.  */);
 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.  */);