(Faccept_process_output): Revert 2006-03-22 change so
[bpt/emacs.git] / src / process.c
index 1c0b196..5452055 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,
-                 2005, 2006 Free Software Foundation, Inc.
+                 2005, 2006, 2007 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -318,6 +318,12 @@ static int read_process_output P_ ((Lisp_Object, int));
 #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;
@@ -386,15 +392,13 @@ struct sockaddr_and_len {
 #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;
 
+/* 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>
@@ -414,10 +418,10 @@ 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
@@ -619,11 +623,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 ();
 
@@ -696,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]);
+  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,
@@ -777,6 +782,16 @@ get_process (name)
   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
@@ -789,8 +804,7 @@ nil, indicating the current buffer's process.  */)
   process = get_process (process);
   p = XPROCESS (process);
 
-  p->raw_status_low = Qnil;
-  p->raw_status_high = Qnil;
+  p->raw_status_new = 0;
   if (NETCONN1_P (p))
     {
       p->status = Fcons (Qexit, Fcons (make_number (0), Qnil));
@@ -799,12 +813,35 @@ nil, indicating the current buffer's process.  */)
     }
   else if (XINT (p->infd) >= 0)
     {
-      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);
+#ifdef SIGCHLD
+      Lisp_Object symbol;
+      /* Assignment to EMACS_INT stops GCC whining about limited range
+        of data type.  */
+      EMACS_INT pid = p->pid;
+
+      /* No problem storing the pid here, as it is still in Vprocess_alist.  */
+      deleted_pid_list = Fcons (make_fixnum_or_float (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))
+       deleted_pid_list
+         = Fdelete (make_fixnum_or_float (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;
@@ -840,7 +877,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))
@@ -865,7 +902,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));
@@ -879,8 +916,13 @@ For a network connection, this value is nil.  */)
      (process)
      register Lisp_Object process;
 {
+  /* Assignment to EMACS_INT stops GCC whining about limited range of
+     data type.  */
+  EMACS_INT pid;
+
   CHECK_PROCESS (process);
-  return XPROCESS (process)->pid;
+  pid = XPROCESS (process)->pid;
+  return (pid ? make_fixnum_or_float (pid) : Qnil);
 }
 
 DEFUN ("process-name", Fprocess_name, Sprocess_name, 1, 1, 0,
@@ -1226,7 +1268,7 @@ Returns nil if format of ADDRESS is invalid.  */)
   if (VECTORP (address))  /* AF_INET or AF_INET6 */
     {
       register struct Lisp_Vector *p = XVECTOR (address);
-      Lisp_Object args[6];
+      Lisp_Object args[10];
       int nargs, i;
 
       if (p->size == 4 || (p->size == 5 && !NILP (omit_port)))
@@ -1253,7 +1295,20 @@ Returns nil if format of ADDRESS is invalid.  */)
        return Qnil;
 
       for (i = 0; i < nargs; i++)
-       args[i+1] = p->contents[i];
+       {
+         EMACS_INT element = XINT (p->contents[i]);
+
+         if (element < 0 || element > 65535)
+           return Qnil;
+
+         if (nargs <= 5         /* IPv4 */
+             && i < 4           /* host, not port */
+             && element > 255)
+           return Qnil;
+
+         args[i+1] = p->contents[i];
+       }
+
       return Fformat (nargs+1, args);
     }
 
@@ -1263,7 +1318,6 @@ Returns nil if format of ADDRESS is invalid.  */)
       args[0] = build_string ("<Family %d>");
       args[1] = Fcar (address);
       return Fformat (2, args);
-
     }
 
   return Qnil;
@@ -1279,6 +1333,7 @@ list_processes_1 (query_only)
   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   */
@@ -1362,13 +1417,12 @@ 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))
        symbol = XCAR (p->status);
 
-
       if (EQ (symbol, Qsignal))
        {
          Lisp_Object tem;
@@ -1405,8 +1459,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))
@@ -1470,6 +1524,8 @@ list_processes_1 (query_only)
          insert_string ("\n");
        }
     }
+  if (exited)
+    status_notify (NULL);
   return Qnil;
 }
 
@@ -1502,13 +1558,19 @@ DEFUN ("start-process", Fstart_process, Sstart_process, 3, MANY, 0,
        doc: /* Start a program in a subprocess.  Return the process object for it.
 NAME is name for process.  It is modified if necessary to make it unique.
 BUFFER is the buffer (or buffer name) to associate with the process.
- Process output goes at end of that buffer, unless you specify
- an output stream or filter function to handle the output.
- BUFFER may be also nil, meaning that this process is not associated
- with any buffer.
+
+Process output (both standard output and standard error streams) goes
+at end of BUFFER, unless you specify an output stream or filter
+function to handle the output.  BUFFER may also be nil, meaning that
+this process is not associated with any buffer.
+
 PROGRAM is the program file name.  It is searched for in PATH.
 Remaining arguments are strings to give program as arguments.
 
+If you want to separate standard output from standard error, invoke
+the command through a shell and redirect one of them using the shell
+syntax.
+
 usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS)  */)
      (nargs, args)
      int nargs;
@@ -1734,7 +1796,7 @@ 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;
@@ -1774,7 +1836,8 @@ create_process (process, new_argv, current_dir)
      char **new_argv;
      Lisp_Object current_dir;
 {
-  int pid, inchannel, outchannel;
+  int inchannel, outchannel;
+  pid_t pid;
   int sv[2];
 #ifdef POSIX_SIGNALS
   sigset_t procmask;
@@ -1945,7 +2008,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;
 
@@ -2136,7 +2199,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);
@@ -2322,7 +2385,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)
@@ -2336,7 +2403,6 @@ conv_lisp_to_sockaddr (family, address, sa, len)
   register int i;
 
   bzero (sa, len);
-  sa->sa_family = family;
 
   if (VECTORP (address))
     {
@@ -2348,6 +2414,7 @@ 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)
@@ -2363,9 +2430,10 @@ conv_lisp_to_sockaddr (family, address, sa, len)
                int j = XFASTINT (p->contents[i]) & 0xffff;
                ip6[i] = ntohs (j);
              }
-         return;
+         sa->sa_family = family;
        }
 #endif
+      return;
     }
   else if (STRINGP (address))
     {
@@ -2376,6 +2444,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;
@@ -2856,7 +2925,7 @@ usage: (make-network-process &rest ARGS)  */)
   /* Make QCaddress an alias for :local (server) or :remote (client).  */
   QCaddress = is_server ? QClocal : QCremote;
 
-  /* :wait BOOL */
+  /* :nowait BOOL */
   if (!is_server && socktype == SOCK_STREAM
       && (tem = Fplist_get (contact, QCnowait), !NILP (tem)))
     {
@@ -3284,13 +3353,17 @@ usage: (make-network-process &rest ARGS)  */)
 #endif
     }
 
+  immediate_quit = 0;
+
 #ifdef HAVE_GETADDRINFO
   if (res != &ai)
-    freeaddrinfo (res);
+    {
+      BLOCK_INPUT;
+      freeaddrinfo (res);
+      UNBLOCK_INPUT;
+    }
 #endif
 
-  immediate_quit = 0;
-
   /* Discard the unwind protect for closing S, if any.  */
   specpdl_ptr = specpdl + count1;
 
@@ -3349,7 +3422,7 @@ 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)
@@ -3838,62 +3911,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
+
+Non-nil second arg SECONDS and third arg MICROSEC are number of
 seconds and microseconds to wait; return after that much time whether
-or not there is input.
+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, microsec, just_this_one)
+     register Lisp_Object process, seconds, microsec, 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;
-
-       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 (microsec))
+       {
+         int carry;
+         usecs += XINT (microsec);
+         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
-    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 :
@@ -4067,7 +4138,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;
@@ -4123,12 +4194,39 @@ server_accept_connection (server, channel)
    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 ()
 {
 }
 
+/* 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.
 
@@ -4186,9 +4284,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;
-  /* 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
@@ -4199,6 +4295,8 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
   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,
@@ -4367,9 +4465,9 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
 
       /* 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))
        {
@@ -4725,8 +4823,8 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
                 subprocess termination and SIGCHLD.  */
              else if (nread == 0 && !NETCONN_P (proc))
                ;
-#endif                         /* O_NDELAY */
-#endif                         /* O_NONBLOCK */
+#endif /* O_NDELAY */
+#endif /* O_NONBLOCK */
 #ifdef HAVE_PTYS
              /* On some OSs with ptys, when the process on one end of
                 a pty exits, the other end gets an error reading with
@@ -4737,11 +4835,17 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
                 get a SIGCHLD).
 
                 However, it has been known to happen that the SIGCHLD
-                got lost.  So raise the signl again just in case.
+                got lost.  So raise the signal again just in case.
                 It can't hurt.  */
              else if (nread == -1 && errno == EIO)
-               kill (getpid (), SIGCHLD);
-#endif                         /* HAVE_PTYS */
+               {
+                 /* Clear the descriptor now, so we only raise the signal once.  */
+                 FD_CLR (channel, &input_wait_mask);
+                 FD_CLR (channel, &non_keyboard_wait_mask);
+
+                 kill (getpid (), SIGCHLD);
+               }
+#endif /* HAVE_PTYS */
              /* If we can detect process termination, don't consider the process
                 gone just because its pipe is closed.  */
 #ifdef SIGCHLD
@@ -4753,7 +4857,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
@@ -4825,7 +4929,7 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
        }                       /* 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.
@@ -5062,10 +5166,17 @@ read_process_output (proc, channel)
              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;
+      if (carryover < 0)
+       abort ();
+
       if (SCHARS (p->decoding_buf) < carryover)
        p->decoding_buf = make_uninit_string (carryover);
       bcopy (chars + coding->consumed, SDATA (p->decoding_buf),
@@ -5102,7 +5213,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
-          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 ();
 
@@ -5169,14 +5280,22 @@ read_process_output (proc, channel)
              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;
+      if (carryover < 0)
+       abort ();
+
       if (SCHARS (p->decoding_buf) < carryover)
        p->decoding_buf = make_uninit_string (carryover);
       bcopy (chars + coding->consumed, SDATA (p->decoding_buf),
             carryover);
       XSETINT (p->decoding_carryover, carryover);
+
       /* Adjust the multibyteness of TEXT to that of the buffer.  */
       if (NILP (current_buffer->enable_multibyte_characters)
          != ! STRING_MULTIBYTE (text))
@@ -5290,7 +5409,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));
@@ -5311,6 +5430,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);
+      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.  */
@@ -5554,8 +5675,7 @@ send_process (proc, buf, len, object)
       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);
@@ -5569,6 +5689,91 @@ send_process (proc, buf, len, object)
   UNGCPRO;
 }
 
+static Lisp_Object
+send_process_object_unwind (buf)
+     Lisp_Object buf;
+{
+  Lisp_Object tembuf;
+
+  if (XBUFFER (buf) == current_buffer)
+    return Qnil;
+  tembuf = Fcurrent_buffer ();
+  Fset_buffer (buf);
+  Fkill_buffer (tembuf);
+  return Qnil;
+}
+
+/* Send current contents of region between START and END to PROC.
+   If START is a string, send it instead.
+   This function can evaluate Lisp code and can garbage collect.  */
+
+static void
+send_process_object (proc, start, end)
+     Lisp_Object proc, start, end;
+{
+  int count = SPECPDL_INDEX ();
+  Lisp_Object object = STRINGP (start) ? start : Fcurrent_buffer ();
+  struct buffer *given_buffer = current_buffer;
+  unsigned char *buf;
+  int len;
+
+  record_unwind_protect (send_process_object_unwind, Fcurrent_buffer ());
+
+  if (STRINGP (object) ? STRING_MULTIBYTE (object)
+      : ! NILP (XBUFFER (object)->enable_multibyte_characters))
+    {
+      struct Lisp_Process *p = XPROCESS (proc);
+      struct coding_system *coding;
+
+      if (p->raw_status_new)
+       update_status (p);
+      if (! EQ (p->status, Qrun))
+       error ("Process %s not running", SDATA (p->name));
+      if (XINT (p->outfd) < 0)
+       error ("Output file descriptor of %s is closed", SDATA (p->name));
+
+      coding = proc_encode_coding_system[XINT (p->outfd)];
+      if (! EQ (coding->symbol, p->encode_coding_system))
+       /* The coding system for encoding was changed to raw-text
+          because we sent a unibyte text previously.  Now we are
+          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 (! NILP (coding->pre_write_conversion))
+       {
+         struct gcpro gcpro1, gcpro2;
+
+         GCPRO2 (proc, object);
+         call2 (coding->pre_write_conversion, start, end);
+         UNGCPRO;
+         if (given_buffer != current_buffer)
+           {
+             start = make_number (BEGV), end = make_number (ZV);
+             object = Fcurrent_buffer ();
+           }
+       }
+    }
+
+  if (BUFFERP (object))
+    {
+      EMACS_INT start_byte;
+
+      if (XINT (start) < GPT && XINT (end) > GPT)
+       move_gap (XINT (end));
+      start_byte = CHAR_TO_BYTE (XINT (start));
+      buf = BYTE_POS_ADDR (start_byte);
+      len = CHAR_TO_BYTE (XINT (end)) - start_byte;
+    }
+  else
+    {
+      buf = SDATA (object);
+      len = SBYTES (object);
+    }
+  send_process (proc, buf, len, object);
+
+  unbind_to (count, Qnil);
+}
+
 DEFUN ("process-send-region", Fprocess_send_region, Sprocess_send_region,
        3, 3, 0,
        doc: /* Send current contents of region as input to PROCESS.
@@ -5582,19 +5787,10 @@ Output from processes can arrive in between bunches.  */)
      Lisp_Object process, start, end;
 {
   Lisp_Object proc;
-  int start1, end1;
 
   proc = get_process (process);
   validate_region (&start, &end);
-
-  if (XINT (start) < GPT && XINT (end) > GPT)
-    move_gap (XINT (start));
-
-  start1 = CHAR_TO_BYTE (XINT (start));
-  end1 = CHAR_TO_BYTE (XINT (end));
-  send_process (proc, BYTE_POS_ADDR (start1), end1 - start1,
-               Fcurrent_buffer ());
-
+  send_process_object (proc, start, end);
   return Qnil;
 }
 
@@ -5612,8 +5808,7 @@ Output from processes can arrive in between bunches.  */)
   Lisp_Object proc;
   CHECK_STRING (string);
   proc = get_process (process);
-  send_process (proc, SDATA (string),
-               SBYTES (string), string);
+  send_process_object (proc, string, Qnil);
   return Qnil;
 }
 \f
@@ -5670,7 +5865,7 @@ return t unconditionally.  */)
 
   gid = emacs_get_tty_pgrp (p);
 
-  if (gid == XFASTINT (p->pid))
+  if (gid == p->pid)
     return Qnil;
   return Qt;
 }
@@ -5717,7 +5912,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
@@ -5836,7 +6031,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.
@@ -5846,12 +6041,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;
     }
 
@@ -5859,8 +6054,7 @@ 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)
@@ -5879,7 +6073,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));
@@ -5891,7 +6085,7 @@ process_send_signal (process, signo, current_group, nomsg)
      obvious alternative.  */
   if (no_pgrp)
     {
-      kill (XFASTINT (p->pid), signo);
+      kill (p->pid, signo);
       return;
     }
 
@@ -5904,7 +6098,7 @@ process_send_signal (process, signo, current_group, nomsg)
     }
   else
     {
-      gid = - XFASTINT (p->pid);
+      gid = - p->pid;
       kill (gid, signo);
     }
 #else /* ! defined (TIOCSIGSEND) */
@@ -6017,18 +6211,24 @@ If PROCESS is a network process, resume handling of incoming traffic.  */)
 DEFUN ("signal-process", Fsignal_process, Ssignal_process,
        2, 2, "sProcess (name or number): \nnSignal code: ",
        doc: /* Send PROCESS the signal with code SIGCODE.
-PROCESS may also be an integer specifying the process id of the
+PROCESS may also be a number specifying the process id of the
 process to signal; in this case, the process need not be a child of
 this Emacs.
 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_DATA (process);
       goto got_it;
     }
 
@@ -6037,8 +6237,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;
@@ -6051,13 +6251,13 @@ 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:
 
-#define handle_signal(NAME, VALUE)             \
-  else if (!strcmp (name, NAME))               \
+#define parse_signal(NAME, VALUE)              \
+  else if (!xstricmp (name, NAME))             \
     XSETINT (sigcode, VALUE)
 
   if (INTEGERP (sigcode))
@@ -6069,108 +6269,108 @@ 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))
+      if (!strncmp(name, "SIG", 3) || !strncmp(name, "sig", 3))
        name += 3;
 
       if (0)
        ;
+#ifdef SIGUSR1
+      parse_signal ("usr1", SIGUSR1);
+#endif
+#ifdef SIGUSR2
+      parse_signal ("usr2", SIGUSR2);
+#endif
+#ifdef SIGTERM
+      parse_signal ("term", SIGTERM);
+#endif
 #ifdef SIGHUP
-      handle_signal ("HUP", SIGHUP);
+      parse_signal ("hup", SIGHUP);
 #endif
 #ifdef SIGINT
-      handle_signal ("INT", SIGINT);
+      parse_signal ("int", SIGINT);
 #endif
 #ifdef SIGQUIT
-      handle_signal ("QUIT", SIGQUIT);
+      parse_signal ("quit", SIGQUIT);
 #endif
 #ifdef SIGILL
-      handle_signal ("ILL", SIGILL);
+      parse_signal ("ill", SIGILL);
 #endif
 #ifdef SIGABRT
-      handle_signal ("ABRT", SIGABRT);
+      parse_signal ("abrt", SIGABRT);
 #endif
 #ifdef SIGEMT
-      handle_signal ("EMT", SIGEMT);
+      parse_signal ("emt", SIGEMT);
 #endif
 #ifdef SIGKILL
-      handle_signal ("KILL", SIGKILL);
+      parse_signal ("kill", SIGKILL);
 #endif
 #ifdef SIGFPE
-      handle_signal ("FPE", SIGFPE);
+      parse_signal ("fpe", SIGFPE);
 #endif
 #ifdef SIGBUS
-      handle_signal ("BUS", SIGBUS);
+      parse_signal ("bus", SIGBUS);
 #endif
 #ifdef SIGSEGV
-      handle_signal ("SEGV", SIGSEGV);
+      parse_signal ("segv", SIGSEGV);
 #endif
 #ifdef SIGSYS
-      handle_signal ("SYS", SIGSYS);
+      parse_signal ("sys", SIGSYS);
 #endif
 #ifdef SIGPIPE
-      handle_signal ("PIPE", SIGPIPE);
+      parse_signal ("pipe", SIGPIPE);
 #endif
 #ifdef SIGALRM
-      handle_signal ("ALRM", SIGALRM);
-#endif
-#ifdef SIGTERM
-      handle_signal ("TERM", SIGTERM);
+      parse_signal ("alrm", SIGALRM);
 #endif
 #ifdef SIGURG
-      handle_signal ("URG", SIGURG);
+      parse_signal ("urg", SIGURG);
 #endif
 #ifdef SIGSTOP
-      handle_signal ("STOP", SIGSTOP);
+      parse_signal ("stop", SIGSTOP);
 #endif
 #ifdef SIGTSTP
-      handle_signal ("TSTP", SIGTSTP);
+      parse_signal ("tstp", SIGTSTP);
 #endif
 #ifdef SIGCONT
-      handle_signal ("CONT", SIGCONT);
+      parse_signal ("cont", SIGCONT);
 #endif
 #ifdef SIGCHLD
-      handle_signal ("CHLD", SIGCHLD);
+      parse_signal ("chld", SIGCHLD);
 #endif
 #ifdef SIGTTIN
-      handle_signal ("TTIN", SIGTTIN);
+      parse_signal ("ttin", SIGTTIN);
 #endif
 #ifdef SIGTTOU
-      handle_signal ("TTOU", SIGTTOU);
+      parse_signal ("ttou", SIGTTOU);
 #endif
 #ifdef SIGIO
-      handle_signal ("IO", SIGIO);
+      parse_signal ("io", SIGIO);
 #endif
 #ifdef SIGXCPU
-      handle_signal ("XCPU", SIGXCPU);
+      parse_signal ("xcpu", SIGXCPU);
 #endif
 #ifdef SIGXFSZ
-      handle_signal ("XFSZ", SIGXFSZ);
+      parse_signal ("xfsz", SIGXFSZ);
 #endif
 #ifdef SIGVTALRM
-      handle_signal ("VTALRM", SIGVTALRM);
+      parse_signal ("vtalrm", SIGVTALRM);
 #endif
 #ifdef SIGPROF
-      handle_signal ("PROF", SIGPROF);
+      parse_signal ("prof", SIGPROF);
 #endif
 #ifdef SIGWINCH
-      handle_signal ("WINCH", SIGWINCH);
+      parse_signal ("winch", SIGWINCH);
 #endif
 #ifdef SIGINFO
-      handle_signal ("INFO", SIGINFO);
-#endif
-#ifdef SIGUSR1
-      handle_signal ("USR1", SIGUSR1);
-#endif
-#ifdef SIGUSR2
-      handle_signal ("USR2", SIGUSR2);
+      parse_signal ("info", SIGINFO);
 #endif
       else
        error ("Undefined signal name %s", name);
     }
 
-#undef handle_signal
+#undef parse_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,
@@ -6194,7 +6394,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));
@@ -6219,7 +6419,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.  */
@@ -6229,6 +6429,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])
@@ -6294,6 +6496,7 @@ kill_buffer_processes (buffer)
    ** 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;
@@ -6312,7 +6515,7 @@ sigchld_handler (signo)
 
   while (1)
     {
-      register int pid;
+      pid_t pid;
       WAITTYPE w;
       Lisp_Object tail;
 
@@ -6322,7 +6525,7 @@ sigchld_handler (signo)
 #endif /* no WUNTRACED */
       /* Keep trying to get a status until we get a definitive result.  */
       do
-       {
+        {
          errno = 0;
          pid = wait3 (&w, WNOHANG | WUNTRACED, 0);
        }
@@ -6351,12 +6554,25 @@ sigchld_handler (signo)
 
       /* Find the process that signaled us, and record its status.  */
 
+      /* The process can have been deleted by Fdelete_process.  */
+      for (tail = deleted_pid_list; GC_CONSP (tail); tail = XCDR (tail))
+       {
+         Lisp_Object xpid = XCAR (tail);
+         if ((GC_INTEGERP (xpid) && pid == (pid_t) XINT (xpid))
+             || (GC_FLOATP (xpid) && pid == (pid_t) XFLOAT_DATA (xpid)))
+           {
+             XSETCAR (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);
-         if (GC_EQ (p->childp, Qt) && XINT (p->pid) == pid)
+         if (GC_EQ (p->childp, Qt) && p->pid == pid)
            break;
          p = 0;
        }
@@ -6368,7 +6584,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;
          }
@@ -6381,8 +6597,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))
@@ -6402,8 +6618,8 @@ sigchld_handler (signo)
            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;
@@ -6420,6 +6636,9 @@ sigchld_handler (signo)
            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.
@@ -6436,6 +6655,7 @@ sigchld_handler (signo)
 #endif /* USG, but not HPUX with WNOHANG */
     }
 }
+#endif /* SIGCHLD */
 \f
 
 static Lisp_Object
@@ -6467,6 +6687,9 @@ exec_sentinel (proc, reason)
   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;
@@ -6523,7 +6746,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
-       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 ();
 
@@ -6579,7 +6802,7 @@ status_notify (deleting_process)
          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);
 
@@ -6796,6 +7019,8 @@ init_process ()
 {
   register int i;
 
+  inhibit_sentinels = 0;
+
 #ifdef SIGCHLD
 #ifndef CANNOT_DUMP
   if (! noninteractive || initialized)
@@ -6821,6 +7046,9 @@ init_process ()
   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;
@@ -6959,10 +7187,13 @@ syms_of_process ()
   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.
-nil means don't delete them until `list-processes' is run.  */);
+A value of nil means don't delete them until `list-processes' is run.  */);
 
   delete_exited_processes = 1;
 
@@ -6981,7 +7212,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
-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.  */);