Use XCAR, XCDR, XFLOAT_DATA instead of explicit member access.
[bpt/emacs.git] / src / process.c
index 2ca7525..a67aeb3 100644 (file)
@@ -331,10 +331,10 @@ decode_status (l, symbol, code, coredump)
     }
   else
     {
-      *symbol = XCONS (l)->car;
-      tem = XCONS (l)->cdr;
-      *code = XFASTINT (XCONS (tem)->car);
-      tem = XCONS (tem)->cdr;
+      *symbol = XCAR (l);
+      tem = XCDR (l);
+      *code = XFASTINT (XCAR (tem));
+      tem = XCDR (tem);
       *coredump = !NILP (tem);
     }
 }
@@ -547,7 +547,7 @@ DEFUN ("get-process", Fget_process, Sget_process, 1, 1, 0,
 }
 
 DEFUN ("get-buffer-process", Fget_buffer_process, Sget_buffer_process, 1, 1, 0,
-  "Return the (or, a) process associated with BUFFER.\n\
+  "Return the (or a) process associated with BUFFER.\n\
 BUFFER may be a buffer or the name of one.")
   (buffer)
      register Lisp_Object buffer;
@@ -635,7 +635,8 @@ nil, indicating the current buffer's process.")
 }
 \f
 DEFUN ("process-status", Fprocess_status, Sprocess_status, 1, 1, 0,
-  "Return the status of PROCESS: a symbol, one of these:\n\
+  "Return the status of PROCESS.\n\
+The returned value is one of the following symbols:\n\
 run  -- for a process that is running.\n\
 stop -- for a process stopped but continuable.\n\
 exit -- for a process that has exited.\n\
@@ -643,7 +644,7 @@ signal -- for a process that has got a fatal signal.\n\
 open -- for a network stream connection that is open.\n\
 closed -- for a network stream connection that is closed.\n\
 nil -- if arg is a process name and no such process exists.\n\
-PROCESS may be a process, a buffer, the name of a process or buffer, or\n\
+PROCESS may be a process, a buffer, the name of a process, or\n\
 nil, indicating the current buffer's process.")
   (process)
      register Lisp_Object process;
@@ -664,7 +665,7 @@ nil, indicating the current buffer's process.")
     update_status (p);
   status = p->status;
   if (CONSP (status))
-    status = XCONS (status)->car;
+    status = XCAR (status);
   if (NETCONN_P (process))
     {
       if (EQ (status, Qrun))
@@ -686,7 +687,7 @@ If PROCESS has not yet exited or died, return 0.")
   if (!NILP (XPROCESS (process)->raw_status_low))
     update_status (XPROCESS (process));
   if (CONSP (XPROCESS (process)->status))
-    return XCONS (XCONS (XPROCESS (process)->status)->cdr)->car;
+    return XCAR (XCDR (XPROCESS (process)->status));
   return make_number (0);
 }
 
@@ -751,8 +752,7 @@ DEFUN ("set-process-buffer", Fset_process_buffer, Sset_process_buffer,
 DEFUN ("process-buffer", Fprocess_buffer, Sprocess_buffer,
   1, 1, 0,
   "Return the buffer PROCESS is associated with.\n\
-Output from PROCESS is inserted in this buffer\n\
-unless PROCESS has a filter.")
+Output from PROCESS is inserted in this buffer unless PROCESS has a filter.")
   (process)
      register Lisp_Object process;
 {
@@ -841,7 +841,7 @@ DEFUN ("set-process-window-size", Fset_process_window_size,
   CHECK_NATNUM (height, 0);
   CHECK_NATNUM (width, 0);
   if (set_window_size (XINT (XPROCESS (process)->infd),
-                      XINT (height), XINT(width)) <= 0)
+                      XINT (height), XINT (width)) <= 0)
     return Qnil;
   else
     return Qt;
@@ -917,9 +917,9 @@ For a net connection, the value is a cons cell of the form (HOST SERVICE).")
 #if 0 /* Turned off because we don't currently record this info
         in the process.  Perhaps add it.  */
 DEFUN ("process-connection", Fprocess_connection, Sprocess_connection, 1, 1, 0,
- "Return the connection type of `PROCESS'.\n\
-The value is `nil' for a pipe,\n\
-`t' or `pty' for a pty, or `stream' for a socket connection.")
+ "Return the connection type of PROCESS.\n\
+The value is nil for a pipe, t or `pty' for a pty, or `stream' for\n\
+a socket connection.")
   (process)
      Lisp_Object process;
 {
@@ -964,7 +964,7 @@ Proc         Status   Buffer         Tty         Command\n\
        update_status (p);
       symbol = p->status;
       if (CONSP (p->status))
-       symbol = XCONS (p->status)->car;
+       symbol = XCAR (p->status);
 
       
       if (EQ (symbol, Qsignal))
@@ -1024,7 +1024,7 @@ Proc         Status   Buffer         Tty         Command\n\
       if (NETCONN_P (proc))
         {
          sprintf (tembuf, "(network stream connection to %s)\n",
-                  XSTRING (XCONS (p->childp)->car)->data);
+                  XSTRING (XCAR (p->childp))->data);
          insert_string (tembuf);
         }
       else 
@@ -1047,8 +1047,8 @@ Proc         Status   Buffer         Tty         Command\n\
 
 DEFUN ("list-processes", Flist_processes, Slist_processes, 0, 0, "",
   "Display a list of all processes.\n\
-\(Any processes listed as Exited or Signaled are actually eliminated\n\
-after the listing is made.)")
+Any process listed as exited or signaled is actually eliminated\n\
+after the listing is made.")
   ()
 {
   internal_with_output_to_temp_buffer ("*Process List*",
@@ -1226,9 +1226,9 @@ Remaining arguments are strings to give program as arguments.")
        coding_systems = Ffind_operation_coding_system (nargs + 1, args2);
        UNGCPRO;
        if (CONSP (coding_systems))
-         val = XCONS (coding_systems)->car;
+         val = XCAR (coding_systems);
        else if (CONSP (Vdefault_process_coding_system))
-         val = XCONS (Vdefault_process_coding_system)->car;
+         val = XCAR (Vdefault_process_coding_system);
       }
     XPROCESS (proc)->decode_coding_system = val;
 
@@ -1245,9 +1245,9 @@ Remaining arguments are strings to give program as arguments.")
            UNGCPRO;
          }
        if (CONSP (coding_systems))
-         val = XCONS (coding_systems)->cdr;
+         val = XCDR (coding_systems);
        else if (CONSP (Vdefault_process_coding_system))
-         val = XCONS (Vdefault_process_coding_system)->cdr;
+         val = XCDR (Vdefault_process_coding_system);
       }
     XPROCESS (proc)->encode_coding_system = val;
   }
@@ -1379,10 +1379,19 @@ create_process (process, new_argv, current_dir)
     }
 #else /* not SKTPAIR */
     {
-      pipe (sv);
+      int tem;
+      tem = pipe (sv);
+      if (tem < 0)
+       report_file_error ("Creating pipe", Qnil);
       inchannel = sv[0];
       forkout = sv[1];
-      pipe (sv);
+      tem = pipe (sv);
+      if (tem < 0)
+       {
+         close (inchannel);
+         close (forkout);
+         report_file_error ("Creating pipe", Qnil);
+       }
       outchannel = sv[1];
       forkin = sv[0];
     }
@@ -1442,11 +1451,9 @@ create_process (process, new_argv, current_dir)
       /* In unibyte mode, character code conversion should not take
         place but EOL conversion should.  So, setup raw-text or one
         of the subsidiary according to the information just setup.  */
-      if (NILP (Vcoding_system_for_read)
-         && !NILP (XPROCESS (process)->decode_coding_system))
+      if (!NILP (XPROCESS (process)->decode_coding_system))
        setup_raw_text_coding_system (proc_decode_coding_system[inchannel]);
-      if (NILP (Vcoding_system_for_write)
-         && !NILP (XPROCESS (process)->encode_coding_system))
+      if (!NILP (XPROCESS (process)->encode_coding_system))
        setup_raw_text_coding_system (proc_encode_coding_system[outchannel]);
     }
 
@@ -1808,15 +1815,22 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\
 {
   Lisp_Object proc;
   register int i;
+
+#ifndef HAVE_GETADDRINFO
   struct sockaddr_in address;
   struct servent *svc_info;
   struct hostent *host_info_ptr, host_info;
   char *(addr_list[2]);
   IN_ADDR numeric_addr;
-  int s, outch, inch;
-  char errstring[80];
-  int port;
   struct hostent host_info_fixed;
+  int port;
+#else /* HAVE_GETADDRINFO */
+  struct addrinfo hints, *res, *lres;
+  int ret = 0;
+  int xerrno = 0;
+  char *portstring, portbuf[128];
+#endif /* HAVE_GETADDRINFO */
+  int s = -1, outch, inch;
   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
   int retry = 0;
   int count = specpdl_ptr - specpdl;
@@ -1829,6 +1843,23 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\
   GCPRO4 (name, buffer, host, service);
   CHECK_STRING (name, 0);
   CHECK_STRING (host, 0);
+
+#ifdef HAVE_GETADDRINFO
+  /*
+   * SERVICE can either be a string or int.
+   * Convert to a C string for later use by getaddrinfo.
+   */
+  if (INTEGERP (service))
+    {
+      sprintf (portbuf, "%d", XINT (service));
+      portstring = portbuf;
+    }
+  else
+    {
+      CHECK_STRING (service, 0);
+      portstring = XSTRING (service)->data;
+    }
+#else /* ! HAVE_GETADDRINFO */
   if (INTEGERP (service))
     port = htons ((unsigned short) XINT (service));
   else
@@ -1839,6 +1870,8 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\
        error ("Unknown service \"%s\"", XSTRING (service)->data);
       port = svc_info->s_port;
     }
+#endif /* ! HAVE_GETADDRINFO */
+
 
   /* Slow down polling to every ten seconds.
      Some kernels have a bug which causes retrying connect to fail
@@ -1848,6 +1881,61 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\
 #endif
 
 #ifndef TERM
+#ifdef HAVE_GETADDRINFO
+  {
+    immediate_quit = 1;
+    QUIT;
+    memset (&hints, 0, sizeof (hints));
+    hints.ai_flags = 0;
+    hints.ai_family = AF_UNSPEC;
+    hints.ai_socktype = SOCK_STREAM;
+    hints.ai_protocol = 0;
+    ret = getaddrinfo (XSTRING (host)->data, portstring, &hints, &res);
+    if (ret)
+      {
+       error ("%s/%s %s", XSTRING (host)->data, portstring,
+              gai_strerror (ret));
+      }
+    immediate_quit = 0;
+  }
+
+  for (lres = res; lres; lres = lres->ai_next)
+    {
+      s = socket (lres->ai_family, lres->ai_socktype, lres->ai_protocol);
+      if (s < 0) 
+       continue;
+
+      /* Kernel bugs (on Ultrix at least) cause lossage (not just EINTR)
+        when connect is interrupted.  So let's not let it get interrupted.
+        Note we do not turn off polling, because polling is only used
+        when not interrupt_input, and thus not normally used on the systems
+        which have this bug.  On systems which use polling, there's no way
+        to quit if polling is turned off.  */
+      if (interrupt_input)
+       unrequest_sigio ();
+
+      immediate_quit = 1;
+      QUIT;
+
+      ret = connect (s, lres->ai_addr, lres->ai_addrlen);
+      if (ret == 0)
+       break;
+      close (s);
+      s = -1;
+    }
+
+  freeaddrinfo (res);
+  if (s < 0)
+    {
+      if (interrupt_input)
+       request_sigio ();
+
+      errno = xerrno;
+      report_file_error ("connection failed",
+                        Fcons (host, Fcons (name, Qnil)));
+    }
+#else /* ! HAVE_GETADDRINFO */
+
   while (1)
     {
 #ifdef TRY_AGAIN
@@ -1938,6 +2026,7 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\
       report_file_error ("connection failed",
                         Fcons (host, Fcons (name, Qnil)));
     }
+#endif /* ! HAVE_GETADDRINFO */
 
   immediate_quit = 0;
 
@@ -2012,9 +2101,9 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\
        coding_systems = Ffind_operation_coding_system (5, args);
        UNGCPRO;
        if (CONSP (coding_systems))
-         val = XCONS (coding_systems)->car;
+         val = XCAR (coding_systems);
        else if (CONSP (Vdefault_process_coding_system))
-         val = XCONS (Vdefault_process_coding_system)->car;
+         val = XCAR (Vdefault_process_coding_system);
        else
          val = Qnil;
       }
@@ -2035,9 +2124,9 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\
            UNGCPRO;
          }
        if (CONSP (coding_systems))
-         val = XCONS (coding_systems)->cdr;
+         val = XCDR (coding_systems);
        else if (CONSP (Vdefault_process_coding_system))
-         val = XCONS (Vdefault_process_coding_system)->cdr;
+         val = XCDR (Vdefault_process_coding_system);
        else
          val = Qnil;
       }
@@ -2157,6 +2246,9 @@ Return non-nil iff we received any output before the timeout expired.")
   int seconds;
   int useconds;
 
+  if (! NILP (process))
+    CHECK_PROCESS (process, 0);
+
   if (! NILP (timeout_msecs))
     {
       CHECK_NUMBER (timeout_msecs, 2);
@@ -2286,7 +2378,7 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
   /* If waiting for non-nil in a cell, record where.  */
   if (CONSP (read_kbd))
     {
-      wait_for_cell = &XCONS (read_kbd)->car;
+      wait_for_cell = &XCAR (read_kbd);
       XSETFASTINT (read_kbd, 0);
     }
 
@@ -2313,6 +2405,11 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
     {
       int timeout_reduced_for_timers = 0;
 
+#ifdef HAVE_X_WINDOWS
+      if (display_busy_cursor_p)
+       Fx_hide_busy_cursor (Qnil);
+#endif
+
       /* 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.  */
@@ -2484,7 +2581,7 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
       clear_waiting_for_input ();
 
       /*  If we woke up due to SIGWINCH, actually change size now.  */
-      do_pending_window_change ();
+      do_pending_window_change (0);
 
       if (time_limit && nfds == 0 && ! timeout_reduced_for_timers)
        /* We wanted the full specified time, so return now.  */
@@ -2608,7 +2705,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) || wait_for_cell)
-       do_pending_window_change ();
+       do_pending_window_change (0);
 
       /* Check for data from a process.  */
       /* Really FIRST_PROC_DESC should be 0 on Unix,
@@ -2676,9 +2773,13 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
                 Therefore, if we get an error reading and errno =
                 EIO, just continue, because the child process has
                 exited and should clean itself up soon (e.g. when we
-                get a SIGCHLD). */
+                get a SIGCHLD).
+
+                However, it has been known to happen that the SIGCHLD
+                got lost.  So raise the signl again just in case.
+                It can't hurt.  */
              else if (nread == -1 && errno == EIO)
-               ;
+               kill (getpid (), SIGCHLD);
 #endif                         /* HAVE_PTYS */
              /* If we can detect process termination, don't consider the process
                 gone just because its pipe is closed.  */
@@ -2720,6 +2821,12 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
      Turn periodic alarms back on */
   start_polling ();
 #endif
+
+#ifdef HAVE_X_WINDOWS
+  if (display_busy_cursor_p)
+    if (!inhibit_busy_cursor)
+      Fx_show_busy_cursor ();
+#endif
    
   return got_some_input;
 }
@@ -2730,7 +2837,7 @@ static Lisp_Object
 read_process_output_call (fun_and_args)
      Lisp_Object fun_and_args;
 {
-  return apply1 (XCONS (fun_and_args)->car, XCONS (fun_and_args)->cdr);
+  return apply1 (XCAR (fun_and_args), XCDR (fun_and_args));
 }
 
 static Lisp_Object
@@ -2782,7 +2889,7 @@ read_process_output (proc, channel)
   if (vs)
     {
       if (!vs->iosb[0])
-       return(0);              /* Really weird if it does this */
+       return (0);             /* Really weird if it does this */
       if (!(vs->iosb[0] & 1))
        return -1;              /* I/O error */
     }
@@ -2837,7 +2944,12 @@ read_process_output (proc, channel)
 
   /* At this point, NBYTES holds number of characters just received
      (including the one in proc_buffered_char[channel]).  */
-  if (nbytes <= 0) return nbytes;
+  if (nbytes <= 0)
+    {
+      if (nbytes < 0 || coding->mode & CODING_MODE_LAST_BLOCK)
+       return nbytes;
+      coding->mode |= CODING_MODE_LAST_BLOCK;
+    }
 
   /* Now set NBYTES how many bytes we must decode.  */
   nbytes += carryover;
@@ -2957,6 +3069,7 @@ read_process_output (proc, channel)
       Lisp_Object obuffer, okeymap;
       Lisp_Object text;
       int outer_running_asynch_code = running_asynch_code;
+      int waiting = waiting_for_user_input_p;
 
       /* 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.  */
@@ -2984,7 +3097,14 @@ read_process_output (proc, channel)
         save the match data in a special nonrecursive fashion.  */
       running_asynch_code = 1;
 
-      text = make_string_from_bytes (chars, nchars, nbytes);
+      /* The multibyteness of a string given to the filter is decided
+         by which coding system we used for decoding.  */
+      if (coding->type == coding_type_no_conversion
+         || coding->type == coding_type_raw_text)
+       text = make_unibyte_string (chars, nbytes);
+      else
+       text = make_multibyte_string (chars, nchars, nbytes);
+
       internal_condition_case_1 (read_process_output_call,
                                 Fcons (outstream,
                                        Fcons (proc, Fcons (text, Qnil))),
@@ -2998,6 +3118,10 @@ read_process_output (proc, channel)
       /* Handling the process output should not deactivate the mark.  */
       Vdeactivate_mark = odeactivate;
 
+      /* Restore waiting_for_user_input_p as it was
+        when we were called, in case the filter clobbered it.  */
+      waiting_for_user_input_p = waiting;
+
 #if 0 /* Call record_asynch_buffer_change unconditionally,
         because we might have changed minor modes or other things
         that affect key bindings.  */
@@ -3073,7 +3197,10 @@ read_process_output (proc, channel)
          insert_before_markers (temp_buf, nbytes);
        }
       else
-       insert_1_both (chars, nchars, nbytes, 0, 1, 1);
+       {
+         insert_1_both (chars, nchars, nbytes, 0, 1, 1);
+         signal_after_change (opoint, 0, PT - opoint);
+       }
       set_marker_both (p->mark, p->buffer, PT, PT_BYTE);
 
       update_mode_lines++;
@@ -3185,11 +3312,11 @@ send_process (proc, buf, len, object)
 
       /* Remember the offset of data because a string or a buffer may
          be relocated.  Setting OFFSET to -1 means we don't have to
-         care relocation.  */
+         care about relocation.  */
       offset = (BUFFERP (object)
                ? BUF_PTR_BYTE_POS (XBUFFER (object), buf)
                : (STRINGP (object)
-                  ? offset = buf - XSTRING (object)->data
+                  ? buf - XSTRING (object)->data
                   : -1));
 
       if (carryover > 0)
@@ -3202,7 +3329,7 @@ send_process (proc, buf, len, object)
                buf = BUF_BYTE_ADDRESS (XBUFFER (object), offset);
              else if (STRINGP (object))
                buf = offset + XSTRING (object)->data;
-             /* Now we don't have to care relocation.  */
+             /* Now we don't have to care about relocation.  */
              offset = -1;
            }
          bcopy ((XSTRING (XPROCESS (proc)->encoding_buf)->data
@@ -3417,10 +3544,49 @@ Output from processes can arrive in between bunches.")
   return Qnil;
 }
 \f
+DEFUN ("process-running-child-p", Fprocess_running_child_p,
+       Sprocess_running_child_p, 0, 1, 0,
+  "Return t if PROCESS has given the terminal to a child.\n\
+If the operating system does not make it possible to find out,\n\
+return t unconditionally.")
+  (process)
+     Lisp_Object process;
+{
+  /* Initialize in case ioctl doesn't exist or gives an error,
+     in a way that will cause returning t.  */
+  int gid = 0;
+  Lisp_Object proc;
+  struct Lisp_Process *p;
+
+  proc = get_process (process);
+  p = XPROCESS (proc);
+
+  if (!EQ (p->childp, Qt))
+    error ("Process %s is not a subprocess",
+          XSTRING (p->name)->data);
+  if (XINT (p->infd) < 0)
+    error ("Process %s is not active",
+          XSTRING (p->name)->data);
+
+#ifdef TIOCGPGRP 
+  if (!NILP (p->subtty))
+    ioctl (XFASTINT (p->subtty), TIOCGPGRP, &gid);
+  else
+    ioctl (XINT (p->infd), TIOCGPGRP, &gid);
+#endif /* defined (TIOCGPGRP ) */
+
+  if (gid == XFASTINT (p->pid))
+    return Qnil;
+  return Qt;
+}
+\f
 /* send a signal number SIGNO to PROCESS.
-   CURRENT_GROUP means send to the process group that currently owns
-   the terminal being used to communicate with PROCESS.
+   If CURRENT_GROUP is t, that means send to the process group
+   that currently owns the terminal being used to communicate with PROCESS.
    This is used for various commands in shell mode.
+   If CURRENT_GROUP is lambda, that means send to the process group
+   that currently owns the terminal, but only if it is NOT the shell itself.
+
    If NOMSG is zero, insert signal-announcements into process's buffers
    right away.
 
@@ -3576,6 +3742,11 @@ process_send_signal (process, signo, current_group, nomsg)
         the child itself heads the pgrp.  */
       gid = - XFASTINT (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))
+       return;
     }
   else
     gid = - XFASTINT (p->pid);
@@ -3635,14 +3806,17 @@ process_send_signal (process, signo, current_group, nomsg)
 }
 
 DEFUN ("interrupt-process", Finterrupt_process, Sinterrupt_process, 0, 2, 0,
-  "Interrupt process PROCESS.  May be process or name of one.\n\
+  "Interrupt process PROCESS.\n\
 PROCESS may be a process, a buffer, or the name of a process or buffer.\n\
 nil or no arg means current buffer's process.\n\
 Second arg CURRENT-GROUP non-nil means send signal to\n\
 the current process-group of the process's controlling terminal\n\
 rather than to the process's own process group.\n\
 If the process is a shell, this means interrupt current subjob\n\
-rather than the shell.")
+rather than the shell.\n\
+\n\
+If CURRENT-GROUP is `lambda', and if the shell owns the terminal,\n\
+don't send the signal.")
   (process, current_group)
      Lisp_Object process, current_group;
 {
@@ -3824,7 +3998,7 @@ SIGCODE may be an integer, or a symbol whose name is a signal name.")
 
 DEFUN ("process-send-eof", Fprocess_send_eof, Sprocess_send_eof, 0, 1, 0,
   "Make PROCESS see end-of-file in its input.\n\
-Eof comes after any text already sent to it.\n\
+EOF comes after any text already sent to it.\n\
 PROCESS may be a process, a buffer, the name of a process or buffer, or\n\
 nil, indicating the current buffer's process.\n\
 If PROCESS is a network connection, or is a process communicating\n\
@@ -3834,8 +4008,10 @@ text to PROCESS after you call this function.")
      Lisp_Object process;
 {
   Lisp_Object proc;
+  struct coding_system *coding;
 
   proc = get_process (process);
+  coding = proc_encode_coding_system[XINT (XPROCESS (proc)->outfd)];
 
   /* Make sure the process is really alive.  */
   if (! NILP (XPROCESS (proc)->raw_status_low))
@@ -3843,6 +4019,12 @@ text to PROCESS after you call this function.")
   if (! EQ (XPROCESS (proc)->status, Qrun))
     error ("Process %s not running", XSTRING (XPROCESS (proc)->name)->data);
 
+  if (CODING_REQUIRE_FLUSHING (coding))
+    {
+      coding->mode |= CODING_MODE_LAST_BLOCK;
+      send_process (proc, "", 0, Qnil);
+    }
+
 #ifdef VMS
   send_process (proc, "\032", 1, Qnil);        /* ^z */
 #else
@@ -3893,9 +4075,9 @@ kill_buffer_processes (buffer)
 {
   Lisp_Object tail, proc;
 
-  for (tail = Vprocess_alist; GC_CONSP (tail); tail = XCONS (tail)->cdr)
+  for (tail = Vprocess_alist; GC_CONSP (tail); tail = XCDR (tail))
     {
-      proc = XCONS (XCONS (tail)->car)->cdr;
+      proc = XCDR (XCAR (tail));
       if (GC_PROCESSP (proc)
          && (NILP (buffer) || EQ (XPROCESS (proc)->buffer, buffer)))
        {
@@ -3983,9 +4165,9 @@ sigchld_handler (signo)
       /* Find the process that signaled us, and record its status.  */
 
       p = 0;
-      for (tail = Vprocess_alist; CONSP (tail); tail = XCONS (tail)->cdr)
+      for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail))
        {
-         proc = XCONS (XCONS (tail)->car)->cdr;
+         proc = XCDR (XCAR (tail));
          p = XPROCESS (proc);
          if (EQ (p->childp, Qt) && XFASTINT (p->pid) == pid)
            break;
@@ -3995,9 +4177,9 @@ sigchld_handler (signo)
       /* Look for an asynchronous process whose pid hasn't been filled
         in yet.  */
       if (p == 0)
-       for (tail = Vprocess_alist; CONSP (tail); tail = XCONS (tail)->cdr)
+       for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail))
          {
-           proc = XCONS (XCONS (tail)->car)->cdr;
+           proc = XCDR (XCAR (tail));
            p = XPROCESS (proc);
            if (INTEGERP (p->pid) && XINT (p->pid) == -1)
              break;
@@ -4088,7 +4270,7 @@ static Lisp_Object
 exec_sentinel_unwind (data)
      Lisp_Object data;
 {
-  XPROCESS (XCONS (data)->car)->sentinel = XCONS (data)->cdr;
+  XPROCESS (XCAR (data))->sentinel = XCDR (data);
   return Qnil;
 }
 
@@ -4110,6 +4292,7 @@ exec_sentinel (proc, reason)
   register struct Lisp_Process *p = XPROCESS (proc);
   int count = specpdl_ptr - specpdl;
   int outer_running_asynch_code = running_asynch_code;
+  int waiting = waiting_for_user_input_p;
 
   /* 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.  */
@@ -4156,6 +4339,11 @@ exec_sentinel (proc, reason)
   running_asynch_code = outer_running_asynch_code;
 
   Vdeactivate_mark = odeactivate;
+
+  /* Restore waiting_for_user_input_p as it was
+     when we were called, in case the filter clobbered it.  */
+  waiting_for_user_input_p = waiting;
+
 #if 0
   if (! EQ (Fcurrent_buffer (), obuffer)
       || ! EQ (current_buffer->keymap, okeymap))
@@ -4219,7 +4407,7 @@ status_notify ()
          /* If process is terminated, deactivate it or delete it.  */
          symbol = p->status;
          if (CONSP (p->status))
-           symbol = XCONS (p->status)->car;
+           symbol = XCAR (p->status);
 
          if (EQ (symbol, Qsignal) || EQ (symbol, Qexit)
              || EQ (symbol, Qclosed))
@@ -4297,8 +4485,9 @@ status_notify ()
 \f
 DEFUN ("set-process-coding-system", Fset_process_coding_system,
        Sset_process_coding_system, 1, 3, 0,
-  "Set coding systems of PROCESS to DECODING (input from the process) and\n\
-ENCODING (output to the process).")
+  "Set coding systems of PROCESS to DECODING and ENCODING.\n\
+DECODING will be used to decode subprocess output and ENCODING to\n\
+encode subprocess input.")
   (proc, decoding, encoding)
      register Lisp_Object proc, decoding, encoding;
 {
@@ -4500,6 +4689,7 @@ The value takes effect when `start-process' is called.");
   defsubr (&Squit_process);
   defsubr (&Sstop_process);
   defsubr (&Scontinue_process);
+  defsubr (&Sprocess_running_child_p);
   defsubr (&Sprocess_send_eof);
   defsubr (&Ssignal_process);
   defsubr (&Swaiting_for_user_input_p);
@@ -4565,7 +4755,7 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
   /* If waiting for non-nil in a cell, record where.  */
   if (CONSP (read_kbd))
     {
-      wait_for_cell = &XCONS (read_kbd)->car;
+      wait_for_cell = &XCAR (read_kbd);
       XSETFASTINT (read_kbd, 0);
     }
 
@@ -4691,7 +4881,7 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
       clear_waiting_for_input ();
 
       /*  If we woke up due to SIGWINCH, actually change size now.  */
-      do_pending_window_change ();
+      do_pending_window_change (0);
 
       if (time_limit && nfds == 0 && ! timeout_reduced_for_timers)
        /* We waited the full specified time, so return now.  */