]> code.delx.au - gnu-emacs/blobdiff - src/process.c
fileio.c (Fread_file_name): Call x_file_dialog on carbon on
[gnu-emacs] / src / process.c
index 854607a2230332564eaceb44ad8583160a703f76..d20290813e146723f46aecd5c5b4df0a4e6ad940 100644 (file)
@@ -445,10 +445,11 @@ decode_status (l, symbol, code, coredump)
 
 /* Return a string describing a process status list.  */
 
-Lisp_Object
-status_message (status)
-     Lisp_Object status;
+static Lisp_Object
+status_message (p)
+     struct Lisp_Process *p;
 {
+  Lisp_Object status = p->status;
   Lisp_Object symbol;
   int code, coredump;
   Lisp_Object string, string2;
@@ -469,6 +470,8 @@ status_message (status)
     }
   else if (EQ (symbol, Qexit))
     {
+      if (NETCONN1_P (p))
+       return build_string (code == 0 ? "deleted\n" : "connection broken by remote peer\n");
       if (code == 0)
        return build_string ("finished\n");
       string = Fnumber_to_string (make_number (code));
@@ -532,7 +535,7 @@ allocate_pty ()
               three failures in a row before deciding that we've reached the
               end of the ptys.  */
            int failed_count = 0;
-           
+
            if (stat (pty_name, &stb) < 0)
              {
                failed_count++;
@@ -764,6 +767,7 @@ nil, indicating the current buffer's process.  */)
     {
       XPROCESS (process)->status = Fcons (Qexit, Fcons (make_number (0), Qnil));
       XSETINT (XPROCESS (process)->tick, ++process_tick);
+      status_notify ();
     }
   else if (XINT (XPROCESS (process)->infd) >= 0)
     {
@@ -842,7 +846,7 @@ If PROCESS has not yet exited or died, return 0.  */)
 
 DEFUN ("process-id", Fprocess_id, Sprocess_id, 1, 1, 0,
        doc: /* Return the process id of PROCESS.
-This is the pid of the Unix process which PROCESS uses or talks to.
+This is the pid of the external process which PROCESS uses or talks to.
 For a network connection, this value is nil.  */)
      (process)
      register Lisp_Object process;
@@ -1081,7 +1085,7 @@ DEFUN ("set-process-query-on-exit-flag",
        Fset_process_query_on_exit_flag, Sset_process_query_on_exit_flag,
        2, 2, 0,
        doc: /* Specify if query is needed for PROCESS when Emacs is exited.
-If the second argument FLAG is non-nil, emacs will query the user before
+If the second argument FLAG is non-nil, Emacs will query the user before
 exiting if PROCESS is running.  */)
      (process, flag)
      register Lisp_Object process, flag;
@@ -1094,7 +1098,7 @@ exiting if PROCESS is running.  */)
 DEFUN ("process-query-on-exit-flag",
        Fprocess_query_on_exit_flag, Sprocess_query_on_exit_flag,
        1, 1, 0,
-       doc: /* Return the current value of query on exit flag for PROCESS.  */)
+       doc: /* Return the current value of query-on-exit flag for PROCESS.  */)
      (process)
      register Lisp_Object process;
 {
@@ -1457,12 +1461,12 @@ static Lisp_Object start_process_unwind ();
 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.
+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.
-Third arg is program file name.  It is searched for in PATH.
+PROGRAM is the program file name.  It is searched for in PATH.
 Remaining arguments are strings to give program as arguments.
 
 usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS)  */)
@@ -2608,7 +2612,7 @@ successful) or "failed" when the connect completes.  Default is to use
 a blocking connect (i.e. wait) for stream type connections.
 
 :noquery BOOL -- Query the user unless BOOL is non-nil, and process is
-running when emacs is exited.
+running when Emacs is exited.
 
 :stop BOOL -- Start process in the `stopped' state if BOOL non-nil.
 In the stopped state, a server process does not accept new
@@ -2954,7 +2958,7 @@ usage: (make-network-process &rest ARGS)  */)
       struct hostent *host_info_ptr;
 
       /* gethostbyname may fail with TRY_AGAIN, but we don't honour that,
-        as it may `hang' emacs for a very long time.  */
+        as it may `hang' Emacs for a very long time.  */
       immediate_quit = 1;
       QUIT;
       host_info_ptr = gethostbyname (SDATA (host));
@@ -3615,6 +3619,8 @@ FLAGS is the current flags of the interface.  */)
 #endif
 #endif /* HAVE_SOCKETS */
 
+/* Turn off input and output for process PROC.  */
+
 void
 deactivate_process (proc)
      Lisp_Object proc;
@@ -3634,7 +3640,7 @@ deactivate_process (proc)
       p->read_output_skip = Qnil;
     }
 #endif
-      
+
   if (inchannel >= 0)
     {
       /* Beware SIGCHLD hereabouts. */
@@ -3712,7 +3718,7 @@ close_process_descs ()
 }
 \f
 DEFUN ("accept-process-output", Faccept_process_output, Saccept_process_output,
-       0, 3, 0,
+       0, 4, 0,
        doc: /* Allow any pending output from subprocesses to be read by Emacs.
 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
@@ -3720,15 +3726,20 @@ 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.
+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)
-     register Lisp_Object process, timeout, timeout_msecs;
+     (process, timeout, timeout_msecs, just_this_one)
+     register Lisp_Object process, timeout, timeout_msecs, just_this_one;
 {
   int seconds;
   int useconds;
 
   if (! NILP (process))
     CHECK_PROCESS (process);
+  else
+    just_this_one = Qnil;
 
   if (! NILP (timeout_msecs))
     {
@@ -3766,11 +3777,12 @@ Return non-nil iff we received any output before the timeout expired.  */)
   else
     seconds = NILP (process) ? -1 : 0;
 
-  if (NILP (process))
-    XSETFASTINT (process, 0);
-
   return
-    (wait_reading_process_input (seconds, useconds, process, 0)
+    (wait_reading_process_output (seconds, useconds, 0, 0,
+                                 Qnil,
+                                 !NILP (process) ? XPROCESS (process) : NULL,
+                                 NILP (just_this_one) ? 0 :
+                                 !INTEGERP (just_this_one) ? 1 : -1)
      ? Qt : Qnil);
 }
 
@@ -3964,18 +3976,18 @@ server_accept_connection (server, channel)
 
 /* This variable is different from waiting_for_input in keyboard.c.
    It is used to communicate to a lisp process-filter/sentinel (via the
-   function Fwaiting_for_user_input_p below) whether emacs was waiting
+   function Fwaiting_for_user_input_p below) whether Emacs was waiting
    for user-input when that process-filter was called.
    waiting_for_input cannot be used as that is by definition 0 when
    lisp code is being evalled.
    This is also used in record_asynch_buffer_change.
    For that purpose, this must be 0
-   when not inside wait_reading_process_input.  */
+   when not inside wait_reading_process_output.  */
 static int waiting_for_user_input_p;
 
 /* This is here so breakpoints can be put on it.  */
 static void
-wait_reading_process_input_1 ()
+wait_reading_process_output_1 ()
 {
 }
 
@@ -3997,60 +4009,54 @@ wait_reading_process_input_1 ()
      1 to return when input is available, or
      -1 meaning caller will actually read the input, so don't throw to
        the quit handler, or
-     a cons cell, meaning wait until its car is non-nil
-       (and gobble terminal input into the buffer if any arrives), or
-     a process object, meaning wait until something arrives from that
-       process.  The return value is true iff we read some input from
-       that process.
 
    DO_DISPLAY != 0 means redisplay should be done to show subprocess
-   output that arrives.
+     output that arrives.
+
+   If WAIT_FOR_CELL is a cons cell, wait until its car is non-nil
+     (and gobble terminal input into the buffer if any arrives).
+
+   If WAIT_PROC is specified, wait until something arrives from that
+     process.  The return value is true iff we read some input from
+     that process.
 
-   If READ_KBD is a pointer to a struct Lisp_Process, then the
-     function returns true iff we received input from that process
-     before the timeout elapsed.
+   If JUST_WAIT_PROC is non-nil, handle only output from WAIT_PROC
+     (suspending output from other processes).  A negative value
+     means don't run any timers either.
+
+   If WAIT_PROC is specified, then the function returns true iff we
+     received input from that process before the timeout elapsed.
    Otherwise, return true iff we received input from any process.  */
 
 int
-wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
-     int time_limit, microsecs;
-     Lisp_Object read_kbd;
-     int do_display;
+wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
+                            wait_for_cell, wait_proc, just_wait_proc)
+     int time_limit, microsecs, read_kbd, do_display;
+     Lisp_Object wait_for_cell;
+     struct Lisp_Process *wait_proc;
+     int just_wait_proc;
 {
   register int channel, nfds;
-  static SELECT_TYPE Available;
-  static SELECT_TYPE Connecting;
+  SELECT_TYPE Available;
+  SELECT_TYPE Connecting;
   int check_connect, check_delay, no_avail;
   int xerrno;
   Lisp_Object proc;
   EMACS_TIME timeout, end_time;
   int wait_channel = -1;
-  struct Lisp_Process *wait_proc = 0;
   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.  */
-  Lisp_Object wait_for_cell = Qnil;
+  int saved_waiting_for_user_input_p = waiting_for_user_input_p;
 
   FD_ZERO (&Available);
   FD_ZERO (&Connecting);
 
-  /* If read_kbd is a process to watch, set wait_proc and wait_channel
-     accordingly.  */
-  if (PROCESSP (read_kbd))
-    {
-      wait_proc = XPROCESS (read_kbd);
-      wait_channel = XINT (wait_proc->infd);
-      XSETFASTINT (read_kbd, 0);
-    }
-
-  /* If waiting for non-nil in a cell, record where.  */
-  if (CONSP (read_kbd))
-    {
-      wait_for_cell = read_kbd;
-      XSETFASTINT (read_kbd, 0);
-    }
+  /* If wait_proc is a process to watch, set wait_channel accordingly.  */
+  if (wait_proc != NULL)
+    wait_channel = XINT (wait_proc->infd);
 
-  waiting_for_user_input_p = XINT (read_kbd);
+  waiting_for_user_input_p = read_kbd;
 
   /* Since we may need to wait several times,
      compute the absolute time to return at.  */
@@ -4078,8 +4084,12 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
       /* If calling from keyboard input, do not quit
         since we want to return C-g as an input character.
         Otherwise, do pending quit if requested.  */
-      if (XINT (read_kbd) >= 0)
+      if (read_kbd >= 0)
        QUIT;
+#ifdef SYNC_INPUT
+      else if (interrupt_input_pending)
+       handle_async_input ();
+#endif
 
       /* Exit now if the cell we're waiting for became non-nil.  */
       if (! NILP (wait_for_cell) && ! NILP (XCAR (wait_for_cell)))
@@ -4111,7 +4121,8 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
         But not if wait_for_cell; in those cases,
         the wait is supposed to be short,
         and those callers cannot handle running arbitrary Lisp code here.  */
-      if (NILP (wait_for_cell))
+      if (NILP (wait_for_cell)
+         && just_wait_proc >= 0)
        {
          EMACS_TIME timer_delay;
 
@@ -4139,7 +4150,7 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
          while (!detect_input_pending ());
 
          /* If there is unread keyboard input, also return.  */
-         if (XINT (read_kbd) != 0
+         if (read_kbd != 0
              && requeued_events_pending_p ())
            break;
 
@@ -4157,7 +4168,7 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
          else if (time_limit != -1)
            {
              /* This is so a breakpoint can be put here.  */
-             wait_reading_process_input_1 ();
+             wait_reading_process_output_1 ();
            }
        }
 
@@ -4167,7 +4178,7 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
         It is important that we do this before checking for process
         activity.  If we get a SIGCHLD after the explicit checks for
         process activity, timeout is the only way we will know.  */
-      if (XINT (read_kbd) < 0)
+      if (read_kbd < 0)
        set_waiting_for_input (&timeout);
 
       /* If status of something has changed, and no input is
@@ -4179,12 +4190,13 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
          SELECT_TYPE Atemp, Ctemp;
 
          Atemp = input_wait_mask;
-#ifdef MAC_OSX
-          /* On Mac OS X, the SELECT system call always says input is
+#if 0
+          /* On Mac OS X 10.0, the SELECT system call always says input is
              present (for reading) at stdin, even when none is.  This
              causes the call to SELECT below to return 1 and
              status_notify not to be called.  As a result output of
-             subprocesses are incorrectly discarded.  */
+             subprocesses are incorrectly discarded.
+         */
           FD_CLR (0, &Atemp);
 #endif
          Ctemp = connect_wait_mask;
@@ -4246,19 +4258,26 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
 
       /* Wait till there is something to do */
 
-      if (!NILP (wait_for_cell))
+      if (wait_proc && just_wait_proc)
+       {
+         if (XINT (wait_proc->infd) < 0)  /* Terminated */
+           break;
+         FD_SET (XINT (wait_proc->infd), &Available);
+         check_connect = check_delay = 0;
+       }
+      else if (!NILP (wait_for_cell))
        {
          Available = non_process_wait_mask;
          check_connect = check_delay = 0;
        }
       else
        {
-         if (! XINT (read_kbd))
+         if (! read_kbd)
            Available = non_keyboard_wait_mask;
          else
            Available = input_wait_mask;
          check_connect = (num_pending_connects > 0);
-         check_delay = process_output_delay_count;
+         check_delay = wait_channel >= 0 ? 0 : process_output_delay_count;
        }
 
       /* If frame size has changed or the window is newly mapped,
@@ -4270,12 +4289,12 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
        {
          clear_waiting_for_input ();
          redisplay_preserve_echo_area (11);
-         if (XINT (read_kbd) < 0)
+         if (read_kbd < 0)
            set_waiting_for_input (&timeout);
        }
 
       no_avail = 0;
-      if (XINT (read_kbd) && detect_input_pending ())
+      if (read_kbd && detect_input_pending ())
        {
          nfds = 0;
          no_avail = 1;
@@ -4392,10 +4411,10 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
       /* If we are using polling for input,
         and we see input available, make it get read now.
         Otherwise it might not actually get read for a second.
-        And on hpux, since we turn off polling in wait_reading_process_input,
+        And on hpux, since we turn off polling in wait_reading_process_output,
         it might never get read at all if we don't spend much time
-        outside of wait_reading_process_input.  */
-      if (XINT (read_kbd) && interrupt_input
+        outside of wait_reading_process_output.  */
+      if (read_kbd && interrupt_input
          && keyboard_bit_set (&Available)
          && input_polling_used ())
        kill (getpid (), SIGALRM);
@@ -4405,7 +4424,7 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
       /* If there is any, return immediately
         to give it higher priority than subprocesses */
 
-      if (XINT (read_kbd) != 0)
+      if (read_kbd != 0)
        {
          int old_timers_run = timers_run;
          struct buffer *old_buffer = current_buffer;
@@ -4430,7 +4449,7 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
        }
 
       /* If there is unread keyboard input, also return.  */
-      if (XINT (read_kbd) != 0
+      if (read_kbd != 0
          && requeued_events_pending_p ())
        break;
 
@@ -4441,7 +4460,7 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
         That would causes delays in pasting selections, for example.
 
         (We used to do this only if wait_for_cell.)  */
-      if (XINT (read_kbd) == 0 && detect_input_pending ())
+      if (read_kbd == 0 && detect_input_pending ())
        {
          swallow_events (do_display);
 #if 0  /* Exiting when read_kbd doesn't request that seems wrong, though.  */
@@ -4460,7 +4479,7 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
         In that case, there really is no input and no SIGIO,
         but select says there is input.  */
 
-      if (XINT (read_kbd) && interrupt_input
+      if (read_kbd && interrupt_input
          && keyboard_bit_set (&Available) && ! noninteractive)
        kill (getpid (), SIGIO);
 #endif
@@ -4470,7 +4489,7 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
 
       /* If checking input just got us a size-change event from X,
         obey it now if we should.  */
-      if (XINT (read_kbd) || ! NILP (wait_for_cell))
+      if (read_kbd || ! NILP (wait_for_cell))
        do_pending_window_change (0);
 
       /* Check for data from a process.  */
@@ -4576,7 +4595,8 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
                }
            }
 #ifdef NON_BLOCKING_CONNECT
-         if (check_connect && FD_ISSET (channel, &Connecting))
+         if (check_connect && FD_ISSET (channel, &Connecting)
+             && FD_ISSET (channel, &connect_wait_mask))
            {
              struct Lisp_Process *p;
 
@@ -4639,12 +4659,12 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
        }                       /* end for each file descriptor */
     }                          /* end while exit conditions not met */
 
-  waiting_for_user_input_p = 0;
+  waiting_for_user_input_p = saved_waiting_for_user_input_p;
 
   /* If calling from keyboard input, do not quit
      since we want to return C-g as an input character.
      Otherwise, do pending quit if requested.  */
-  if (XINT (read_kbd) >= 0)
+  if (read_kbd >= 0)
     {
       /* Prevent input_pending from remaining set if we quit.  */
       clear_input_pending ();
@@ -4686,7 +4706,7 @@ read_process_output_error_handler (error)
    starting with our buffered-ahead character if we have one.
    Yield number of decoded characters read.
 
-   This function reads at most 1024 characters.
+   This function reads at most 4096 characters.
    If you want to read all available subprocess output,
    you must call it repeatedly until it returns zero.
 
@@ -4706,7 +4726,7 @@ read_process_output (proc, channel)
   register int opoint;
   struct coding_system *coding = proc_decode_coding_system[channel];
   int carryover = XINT (p->decoding_carryover);
-  int readmax = 1024;
+  int readmax = 4096;
 
 #ifdef VMS
   VMS_PROC_STUFF *vs, *get_vms_process_pointer();
@@ -4739,16 +4759,6 @@ read_process_output (proc, channel)
     }
 #else /* not VMS */
 
-#ifdef DATAGRAM_SOCKETS
-  /* A datagram is one packet; allow at least 1500+ bytes of data
-     corresponding to the typical Ethernet frame size.  */
-  if (DATAGRAM_CHAN_P (channel))
-    {
-      /* carryover = 0; */  /* Does carryover make sense for datagrams? */
-      readmax += 1024;
-    }
-#endif
-
   chars = (char *) alloca (carryover + readmax);
   if (carryover)
     /* See the comment above.  */
@@ -4759,16 +4769,16 @@ read_process_output (proc, channel)
   if (DATAGRAM_CHAN_P (channel))
     {
       int len = datagram_address[channel].len;
-      nbytes = recvfrom (channel, chars + carryover, readmax - carryover,
+      nbytes = recvfrom (channel, chars + carryover, readmax,
                         0, datagram_address[channel].sa, &len);
     }
   else
 #endif
   if (proc_buffered_char[channel] < 0)
     {
-      nbytes = emacs_read (channel, chars + carryover, readmax - carryover);
+      nbytes = emacs_read (channel, chars + carryover, readmax);
 #ifdef ADAPTIVE_READ_BUFFERING
-      if (!NILP (p->adaptive_read_buffering))
+      if (nbytes > 0 && !NILP (p->adaptive_read_buffering))
        {
          int delay = XINT (p->read_output_delay);
          if (nbytes < 256)
@@ -4780,7 +4790,7 @@ read_process_output (proc, channel)
                  delay += READ_OUTPUT_DELAY_INCREMENT * 2;
                }
            }
-         else if (delay > 0 && (nbytes == readmax - carryover))
+         else if (delay > 0 && (nbytes == readmax))
            {
              delay -= READ_OUTPUT_DELAY_INCREMENT;
              if (delay == 0)
@@ -4799,7 +4809,7 @@ read_process_output (proc, channel)
     {
       chars[carryover] = proc_buffered_char[channel];
       proc_buffered_char[channel] = -1;
-      nbytes = emacs_read (channel, chars + carryover + 1,  readmax - 1 - carryover);
+      nbytes = emacs_read (channel, chars + carryover + 1,  readmax - 1);
       if (nbytes < 0)
        nbytes = 1;
       else
@@ -4890,6 +4900,8 @@ read_process_output (proc, channel)
        }
 
       carryover = nbytes - coding->consumed;
+      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);
@@ -4994,6 +5006,8 @@ read_process_output (proc, channel)
            }
        }
       carryover = nbytes - coding->consumed;
+      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);
@@ -5056,7 +5070,7 @@ read_process_output (proc, channel)
 
 DEFUN ("waiting-for-user-input-p", Fwaiting_for_user_input_p, Swaiting_for_user_input_p,
        0, 0, 0,
-       doc: /* Returns non-nil if emacs is waiting for input from the user.
+       doc: /* Returns non-nil if Emacs is waiting for input from the user.
 This is intended for use by asynchronous process output filters and sentinels.  */)
      ()
 {
@@ -5297,7 +5311,6 @@ send_process (proc, buf, len, object)
                       that may allow the program
                       to finish doing output and read more.  */
                    {
-                     Lisp_Object zero;
                      int offset = 0;
 
 #ifdef BROKEN_PTY_READ_AFTER_EAGAIN
@@ -5332,11 +5345,10 @@ send_process (proc, buf, len, object)
                      else if (STRINGP (object))
                        offset = buf - SDATA (object);
 
-                     XSETFASTINT (zero, 0);
 #ifdef EMACS_HAS_USECS
-                     wait_reading_process_input (0, 20000, zero, 0);
+                     wait_reading_process_output (0, 20000, 0, 0, Qnil, NULL, 0);
 #else
-                     wait_reading_process_input (1, 0, zero, 0);
+                     wait_reading_process_output (1, 0, 0, 0, Qnil, NULL, 0);
 #endif
 
                      if (BUFFERP (object))
@@ -5439,7 +5451,7 @@ emacs_get_tty_pgrp (p)
 {
   int gid = -1;
 
-#ifdef TIOCGPGRP 
+#ifdef TIOCGPGRP
   if (ioctl (XINT (p->infd), TIOCGPGRP, &gid) == -1 && ! NILP (p->tty_name))
     {
       int fd;
@@ -5542,29 +5554,36 @@ process_send_signal (process, signo, current_group, nomsg)
          work.  If the system has it, use it.  */
 #ifdef HAVE_TERMIOS
       struct termios t;
+      cc_t *sig_char = NULL;
+
+      tcgetattr (XINT (p->infd), &t);
 
       switch (signo)
        {
        case SIGINT:
-         tcgetattr (XINT (p->infd), &t);
-         send_process (proc, &t.c_cc[VINTR], 1, Qnil);
-         return;
+         sig_char = &t.c_cc[VINTR];
+         break;
 
        case SIGQUIT:
-         tcgetattr (XINT (p->infd), &t);
-         send_process (proc, &t.c_cc[VQUIT], 1, Qnil);
-         return;
+         sig_char = &t.c_cc[VQUIT];
+         break;
 
        case SIGTSTP:
-         tcgetattr (XINT (p->infd), &t);
 #if defined (VSWTCH) && !defined (PREFER_VSUSP)
-         send_process (proc, &t.c_cc[VSWTCH], 1, Qnil);
+         sig_char = &t.c_cc[VSWTCH];
 #else
-         send_process (proc, &t.c_cc[VSUSP], 1, Qnil);
+         sig_char = &t.c_cc[VSUSP];
 #endif
-         return;
+         break;
        }
 
+      if (sig_char && *sig_char != CDISABLE)
+       {
+         send_process (proc, sig_char, 1, Qnil);
+         return;
+       }
+      /* If we can't send the signal with a character,
+        fall through and send it another way.  */
 #else /* ! HAVE_TERMIOS */
 
       /* On Berkeley descendants, the following IOCTL's retrieve the
@@ -5621,9 +5640,12 @@ process_send_signal (process, signo, current_group, nomsg)
         you'd better be using one of the alternatives above!  */
 #endif /* ! defined (TCGETA) */
 #endif /* ! defined (TIOCGLTC) && defined (TIOCGETC) */
-#endif /* ! defined HAVE_TERMIOS */
+       /* In this case, the code above should alway returns.  */
        abort ();
-      /* The code above always returns from the function.  */
+#endif /* ! defined HAVE_TERMIOS */
+
+      /* The code above may fall through if it can't
+        handle the signal.  */
 #endif /* defined (SIGNALS_VIA_CHARACTERS) */
 
 #ifdef TIOCGPGRP
@@ -5636,7 +5658,7 @@ process_send_signal (process, signo, current_group, nomsg)
         we should just assume that p->pid is also the process group id.  */
 
       gid = emacs_get_tty_pgrp (p);
-       
+
       if (gid == -1)
        /* If we can't get the information, assume
           the shell owns the tty.  */
@@ -5719,7 +5741,7 @@ process_send_signal (process, signo, current_group, nomsg)
 DEFUN ("interrupt-process", Finterrupt_process, Sinterrupt_process, 0, 2, 0,
        doc: /* Interrupt process PROCESS.
 PROCESS may be a process, a buffer, or the name of a process or buffer.
-nil or no arg means current buffer's process.
+No arg or nil means current buffer's process.
 Second arg CURRENT-GROUP non-nil means send signal to
 the current process-group of the process's controlling terminal
 rather than to the process's own process group.
@@ -6090,7 +6112,10 @@ kill_buffer_processes (buffer)
    queued and the signal-catching function will be continually
    reentered until the queue is empty".  Invoking signal() causes the
    kernel to reexamine the SIGCLD queue.  Fred Fish, UniSoft Systems
-   Inc. */
+   Inc.
+
+   ** Malloc WARNING: This should never call malloc either directly or
+   indirectly; if it does, that is a bug  */
 
 SIGTYPE
 sigchld_handler (signo)
@@ -6192,7 +6217,7 @@ sigchld_handler (signo)
              FD_CLR (XINT (p->infd), &non_keyboard_wait_mask);
            }
 
-         /* Tell wait_reading_process_input that it needs to wake up and
+         /* Tell wait_reading_process_output that it needs to wake up and
             look around.  */
          if (input_available_clear_time)
            EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
@@ -6208,20 +6233,9 @@ sigchld_handler (signo)
          if (WIFEXITED (w))
            synch_process_retcode = WRETCODE (w);
          else if (WIFSIGNALED (w))
-           {
-             int code = WTERMSIG (w);
-             char *signame;
-
-             synchronize_system_messages_locale ();
-             signame = strsignal (code);
-
-             if (signame == 0)
-               signame = "unknown";
+            synch_process_termsig = WTERMSIG (w);
 
-             synch_process_death = signame;
-           }
-
-         /* Tell wait_reading_process_input that it needs to wake up and
+         /* Tell wait_reading_process_output that it needs to wake up and
             look around.  */
          if (input_available_clear_time)
            EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
@@ -6386,7 +6400,7 @@ status_notify ()
          /* Get the text to use for the message.  */
          if (!NILP (p->raw_status_low))
            update_status (p);
-         msg = status_message (p->status);
+         msg = status_message (p);
 
          /* If process is terminated, deactivate it or delete it.  */
          symbol = p->status;
@@ -6472,13 +6486,13 @@ DEFUN ("set-process-coding-system", Fset_process_coding_system,
        doc: /* Set coding systems of PROCESS to DECODING and ENCODING.
 DECODING will be used to decode subprocess output and ENCODING to
 encode subprocess input.  */)
-     (proc, decoding, encoding)
-     register Lisp_Object proc, decoding, encoding;
+     (process, decoding, encoding)
+     register Lisp_Object process, decoding, encoding;
 {
   register struct Lisp_Process *p;
 
-  CHECK_PROCESS (proc);
-  p = XPROCESS (proc);
+  CHECK_PROCESS (process);
+  p = XPROCESS (process);
   if (XINT (p->infd) < 0)
     error ("Input file descriptor of %s closed", SDATA (p->name));
   if (XINT (p->outfd) < 0)
@@ -6488,7 +6502,7 @@ encode subprocess input.  */)
 
   p->decode_coding_system = decoding;
   p->encode_coding_system = encoding;
-  setup_process_coding_systems (proc);
+  setup_process_coding_systems (process);
 
   return Qnil;
 }
@@ -6496,12 +6510,12 @@ encode subprocess input.  */)
 DEFUN ("process-coding-system",
        Fprocess_coding_system, Sprocess_coding_system, 1, 1, 0,
        doc: /* Return a cons of coding systems for decoding and encoding of PROCESS.  */)
-     (proc)
-     register Lisp_Object proc;
+     (process)
+     register Lisp_Object process;
 {
-  CHECK_PROCESS (proc);
-  return Fcons (XPROCESS (proc)->decode_coding_system,
-               XPROCESS (proc)->encode_coding_system);
+  CHECK_PROCESS (process);
+  return Fcons (XPROCESS (process)->decode_coding_system,
+               XPROCESS (process)->encode_coding_system);
 }
 
 DEFUN ("set-process-filter-multibyte", Fset_process_filter_multibyte,
@@ -6511,15 +6525,15 @@ If FLAG is non-nil, the filter is given multibyte strings.
 If FLAG is nil, the filter is given unibyte strings.  In this case,
 all character code conversion except for end-of-line conversion is
 suppressed.  */)
-     (proc, flag)
-     Lisp_Object proc, flag;
+     (process, flag)
+     Lisp_Object process, flag;
 {
   register struct Lisp_Process *p;
 
-  CHECK_PROCESS (proc);
-  p = XPROCESS (proc);
+  CHECK_PROCESS (process);
+  p = XPROCESS (process);
   p->filter_multibyte = flag;
-  setup_process_coding_systems (proc);
+  setup_process_coding_systems (process);
 
   return Qnil;
 }
@@ -6527,13 +6541,13 @@ suppressed.  */)
 DEFUN ("process-filter-multibyte-p", Fprocess_filter_multibyte_p,
        Sprocess_filter_multibyte_p, 1, 1, 0,
        doc: /* Return t if a multibyte string is given to PROCESS's filter.*/)
-     (proc)
-     Lisp_Object proc;
+     (process)
+     Lisp_Object process;
 {
   register struct Lisp_Process *p;
 
-  CHECK_PROCESS (proc);
-  p = XPROCESS (proc);
+  CHECK_PROCESS (process);
+  p = XPROCESS (process);
 
   return (NILP (p->filter_multibyte) ? Qnil : Qt);
 }
@@ -6754,11 +6768,11 @@ The value takes effect when `start-process' is called.  */);
 #ifdef ADAPTIVE_READ_BUFFERING
   DEFVAR_LISP ("process-adaptive-read-buffering", &Vprocess_adaptive_read_buffering,
               doc: /* If non-nil, improve receive buffering by delaying after short reads.
-On some systems, when emacs reads the output from a subprocess, the output data
+On some systems, when Emacs reads the output from a subprocess, the output data
 is read in very small blocks, potentially resulting in very poor performance.
 This behaviour can be remedied to some extent by setting this variable to a
 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.
+allowing 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.  */);
@@ -6863,10 +6877,9 @@ Lisp_Object QCtype;
      1 to return when input is available, or
      -1 means caller will actually read the input, so don't throw to
        the quit handler.
-     a cons cell, meaning wait until its car is non-nil
-       (and gobble terminal input into the buffer if any arrives), or
-     We know that read_kbd will never be a Lisp_Process, since
-     `subprocesses' isn't defined.
+
+   see full version for other parameters. We know that wait_proc will
+     always be NULL, since `subprocesses' isn't defined.
 
    do_display != 0 means redisplay should be done to show subprocess
    output that arrives.
@@ -6874,27 +6887,17 @@ Lisp_Object QCtype;
    Return true iff we received input from any process.  */
 
 int
-wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
-     int time_limit, microsecs;
-     Lisp_Object read_kbd;
-     int do_display;
+wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
+                            wait_for_cell, wait_proc, just_wait_proc)
+     int time_limit, microsecs, read_kbd, do_display;
+     Lisp_Object wait_for_cell;
+     struct Lisp_Process *wait_proc;
+     int just_wait_proc;
 {
   register int nfds;
   EMACS_TIME end_time, timeout;
   SELECT_TYPE waitchannels;
   int xerrno;
-  /* Either nil or a cons cell, the car of which is of interest and
-     may be changed outside of this routine.  */
-  Lisp_Object wait_for_cell;
-
-  wait_for_cell = Qnil;
-
-  /* If waiting for non-nil in a cell, record where.  */
-  if (CONSP (read_kbd))
-    {
-      wait_for_cell = read_kbd;
-      XSETFASTINT (read_kbd, 0);
-    }
 
   /* What does time_limit really mean?  */
   if (time_limit || microsecs)
@@ -6917,7 +6920,7 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
       /* If calling from keyboard input, do not quit
         since we want to return C-g as an input character.
         Otherwise, do pending quit if requested.  */
-      if (XINT (read_kbd) >= 0)
+      if (read_kbd >= 0)
        QUIT;
 
       /* Exit now if the cell we're waiting for became non-nil.  */
@@ -6968,7 +6971,7 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
          while (!detect_input_pending ());
 
          /* If there is unread keyboard input, also return.  */
-         if (XINT (read_kbd) != 0
+         if (read_kbd != 0
              && requeued_events_pending_p ())
            break;
 
@@ -6986,12 +6989,12 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
 
       /* Cause C-g and alarm signals to take immediate action,
         and cause input available signals to zero out timeout.  */
-      if (XINT (read_kbd) < 0)
+      if (read_kbd < 0)
        set_waiting_for_input (&timeout);
 
       /* Wait till there is something to do.  */
 
-      if (! XINT (read_kbd) && NILP (wait_for_cell))
+      if (! read_kbd && NILP (wait_for_cell))
        FD_ZERO (&waitchannels);
       else
        FD_SET (0, &waitchannels);
@@ -7002,11 +7005,11 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
        {
          clear_waiting_for_input ();
          redisplay_preserve_echo_area (15);
-         if (XINT (read_kbd) < 0)
+         if (read_kbd < 0)
            set_waiting_for_input (&timeout);
        }
 
-      if (XINT (read_kbd) && detect_input_pending ())
+      if (read_kbd && detect_input_pending ())
        {
          nfds = 0;
          FD_ZERO (&waitchannels);
@@ -7042,13 +7045,13 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
        kill (getpid (), SIGIO);
 #endif
 #ifdef SIGIO
-      if (XINT (read_kbd) && interrupt_input && (waitchannels & 1))
+      if (read_kbd && interrupt_input && (waitchannels & 1))
        kill (getpid (), SIGIO);
 #endif
 
       /* Check for keyboard input */
 
-      if ((XINT (read_kbd) != 0)
+      if (read_kbd
          && detect_input_pending_run_timers (do_display))
        {
          swallow_events (do_display);
@@ -7057,7 +7060,7 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
        }
 
       /* If there is unread keyboard input, also return.  */
-      if (XINT (read_kbd) != 0
+      if (read_kbd
          && requeued_events_pending_p ())
        break;