(Fwindow_list): Change parameter list to be XEmacs
[bpt/emacs.git] / src / process.c
index 144e69a..cb51af9 100644 (file)
@@ -20,8 +20,8 @@ the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
 
+#define _GNU_SOURCE            /* to get strsignal declared with glibc 2 */
 #include <config.h>
-
 #include <signal.h>
 
 /* This file is split into two parts by the following preprocessor
@@ -44,7 +44,7 @@ Boston, MA 02111-1307, USA.  */
 #include <unistd.h>
 #endif
 
-#ifdef WINDOWSNT
+#if defined(WINDOWSNT) || defined(UNIX98_PTYS)
 #include <stdlib.h>
 #include <fcntl.h>
 #endif /* not WINDOWSNT */
@@ -59,7 +59,7 @@ Boston, MA 02111-1307, USA.  */
 #endif /* NEED_NET_ERRNO_H */
 #endif /* HAVE_SOCKETS */
 
-/* TERM is a poor-man's SLIP, used on Linux.  */
+/* TERM is a poor-man's SLIP, used on GNU/Linux.  */
 #ifdef TERM
 #include <client.h>
 #endif
@@ -104,10 +104,12 @@ Boston, MA 02111-1307, USA.  */
 #include "termhooks.h"
 #include "termopts.h"
 #include "commands.h"
+#include "keyboard.h"
 #include "frame.h"
 #include "blockinput.h"
-#include "keyboard.h"
 #include "dispextern.h"
+#include "composite.h"
+#include "atimer.h"
 
 #define max(a, b) ((a) > (b) ? (a) : (b))
 
@@ -145,8 +147,9 @@ Lisp_Object Qlast_nonmenu_event;
 
 extern void set_waiting_for_input P_ ((EMACS_TIME *));
 
+#ifndef USE_CRT_DLL
 extern int errno;
-extern char *strerror ();
+#endif
 #ifdef VMS
 extern char *sys_errlist[];
 #endif
@@ -155,50 +158,6 @@ extern char *sys_errlist[];
 extern int h_errno;
 #endif
 
-#ifndef HAVE_STRSIGNAL
-#ifndef SYS_SIGLIST_DECLARED
-#ifndef VMS
-#ifndef BSD4_1
-#ifndef WINDOWSNT
-#ifndef LINUX
-extern char *sys_siglist[];
-#endif /* not LINUX */
-#else /* BSD4_1 */
-char *sys_siglist[] =
-  {
-    "bum signal!!",
-    "hangup",
-    "interrupt",
-    "quit",
-    "illegal instruction",
-    "trace trap",
-    "iot instruction",
-    "emt instruction",
-    "floating point exception",
-    "kill",
-    "bus error",
-    "segmentation violation",
-    "bad argument to system call",
-    "write on a pipe with no one to read it",
-    "alarm clock",
-    "software termination signal from kill",
-    "status signal",
-    "sendable stop signal not from tty",
-    "stop signal from tty",
-    "continue a stopped process",
-    "child status has changed",
-    "background read attempted from control tty",
-    "background write attempted from control tty",
-    "input record available at control tty",
-    "exceeded CPU time limit",
-    "exceeded file size limit"
-    };
-#endif /* not WINDOWSNT */
-#endif
-#endif /* VMS */
-#endif /* ! SYS_SIGLIST_DECLARED */
-#endif /* ! HAVE_STRSIGNAL */
-
 /* t means use pty, nil means use a pipe,
    maybe other values to come.  */
 static Lisp_Object Vprocess_connection_type;
@@ -360,7 +319,7 @@ status_message (status)
   if (EQ (symbol, Qsignal) || EQ (symbol, Qstop))
     {
       char *signame;
-      synchronize_messages_locale ();
+      synchronize_system_messages_locale ();
       signame = strsignal (code);
       if (signame == 0)
        signame = "unknown";
@@ -1066,7 +1025,6 @@ static Lisp_Object start_process_unwind ();
 
 DEFUN ("start-process", Fstart_process, Sstart_process, 3, MANY, 0,
   "Start a program in a subprocess.  Return the process object for it.\n\
-Args are NAME BUFFER PROGRAM &rest PROGRAM-ARGS\n\
 NAME is name for process.  It is modified if necessary to make it unique.\n\
 BUFFER is the buffer or (buffer-name) to associate with the process.\n\
  Process output goes at end of that buffer, unless you specify\n\
@@ -1126,63 +1084,6 @@ Remaining arguments are strings to give program as arguments.")
 
   CHECK_STRING (program, 2);
 
-#ifdef VMS
-  /* Make a one member argv with all args concatenated
-     together separated by a blank.  */
-  len = STRING_BYTES (XSTRING (program)) + 2;
-  for (i = 3; i < nargs; i++)
-    {
-      tem = args[i];
-      CHECK_STRING (tem, i);
-      len += STRING_BYTES (XSTRING (tem)) + 1; /* count the blank */
-    }
-  new_argv = (unsigned char *) alloca (len);
-  strcpy (new_argv, XSTRING (program)->data);
-  for (i = 3; i < nargs; i++)
-    {
-      tem = args[i];
-      CHECK_STRING (tem, i);
-      strcat (new_argv, " ");
-      strcat (new_argv, XSTRING (tem)->data);
-    }
-  /* Need to add code here to check for program existence on VMS */
-  
-#else /* not VMS */
-  new_argv = (unsigned char **) alloca ((nargs - 1) * sizeof (char *));
-
-  /* If program file name is not absolute, search our path for it */
-  if (!IS_DIRECTORY_SEP (XSTRING (program)->data[0])
-      && !(XSTRING (program)->size > 1
-          && IS_DEVICE_SEP (XSTRING (program)->data[1])))
-    {
-      struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
-
-      tem = Qnil;
-      GCPRO4 (name, program, buffer, current_dir);
-      openp (Vexec_path, program, EXEC_SUFFIXES, &tem, 1);
-      UNGCPRO;
-      if (NILP (tem))
-       report_file_error ("Searching for program", Fcons (program, Qnil));
-      tem = Fexpand_file_name (tem, Qnil);
-      new_argv[0] = XSTRING (tem)->data;
-    }
-  else
-    {
-      if (!NILP (Ffile_directory_p (program)))
-       error ("Specified program for new process is a directory");
-
-      new_argv[0] = XSTRING (program)->data;
-    }
-
-  for (i = 3; i < nargs; i++)
-    {
-      tem = args[i];
-      CHECK_STRING (tem, i);
-      new_argv[i - 2] = XSTRING (tem)->data;
-    }
-  new_argv[i - 2] = 0;
-#endif /* not VMS */
-
   proc = make_process (name);
   /* If an error occurs and we can't start the process, we want to
      remove it from the process list.  This means that each error
@@ -1211,7 +1112,7 @@ Remaining arguments are strings to give program as arguments.")
     /* Qt denotes we have not yet called Ffind_operation_coding_system.  */
     Lisp_Object coding_systems = Qt;
     Lisp_Object val, *args2;
-    struct gcpro gcpro1;
+    struct gcpro gcpro1, gcpro2;
 
     val = Vcoding_system_for_read;
     if (NILP (val))
@@ -1219,7 +1120,7 @@ Remaining arguments are strings to give program as arguments.")
        args2 = (Lisp_Object *) alloca ((nargs + 1) * sizeof *args2);
        args2[0] = Qstart_process;
        for (i = 0; i < nargs; i++) args2[i + 1] = args[i];
-       GCPRO1 (proc);
+       GCPRO2 (proc, current_dir);
        coding_systems = Ffind_operation_coding_system (nargs + 1, args2);
        UNGCPRO;
        if (CONSP (coding_systems))
@@ -1237,7 +1138,7 @@ Remaining arguments are strings to give program as arguments.")
            args2 = (Lisp_Object *) alloca ((nargs + 1) * sizeof args2);
            args2[0] = Qstart_process;
            for (i = 0; i < nargs; i++) args2[i + 1] = args[i];
-           GCPRO1 (proc);
+           GCPRO2 (proc, current_dir);
            coding_systems = Ffind_operation_coding_system (nargs + 1, args2);
            UNGCPRO;
          }
@@ -1249,6 +1150,73 @@ Remaining arguments are strings to give program as arguments.")
     XPROCESS (proc)->encode_coding_system = val;
   }
 
+#ifdef VMS
+  /* Make a one member argv with all args concatenated
+     together separated by a blank.  */
+  len = STRING_BYTES (XSTRING (program)) + 2;
+  for (i = 3; i < nargs; i++)
+    {
+      tem = args[i];
+      CHECK_STRING (tem, i);
+      len += STRING_BYTES (XSTRING (tem)) + 1; /* count the blank */
+    }
+  new_argv = (unsigned char *) alloca (len);
+  strcpy (new_argv, XSTRING (program)->data);
+  for (i = 3; i < nargs; i++)
+    {
+      tem = args[i];
+      CHECK_STRING (tem, i);
+      strcat (new_argv, " ");
+      strcat (new_argv, XSTRING (tem)->data);
+    }
+  /* Need to add code here to check for program existence on VMS */
+  
+#else /* not VMS */
+  new_argv = (unsigned char **) alloca ((nargs - 1) * sizeof (char *));
+
+  /* If program file name is not absolute, search our path for it */
+  if (!IS_DIRECTORY_SEP (XSTRING (program)->data[0])
+      && !(XSTRING (program)->size > 1
+          && IS_DEVICE_SEP (XSTRING (program)->data[1])))
+    {
+      struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
+
+      tem = Qnil;
+      GCPRO4 (name, program, buffer, current_dir);
+      openp (Vexec_path, program, EXEC_SUFFIXES, &tem, 1);
+      UNGCPRO;
+      if (NILP (tem))
+       report_file_error ("Searching for program", Fcons (program, Qnil));
+      tem = Fexpand_file_name (tem, Qnil);
+      tem = ENCODE_FILE (tem);
+      new_argv[0] = XSTRING (tem)->data;
+    }
+  else
+    {
+      if (!NILP (Ffile_directory_p (program)))
+       error ("Specified program for new process is a directory");
+
+      tem = ENCODE_FILE (program);
+      new_argv[0] = XSTRING (tem)->data;
+    }
+
+  /* Here we encode arguments by the coding system used for sending
+     data to the process.  We don't support using different coding
+     systems for encoding arguments and for encoding data sent to the
+     process.  */
+
+  for (i = 3; i < nargs; i++)
+    {
+      tem = args[i];
+      CHECK_STRING (tem, i);
+      if (STRING_MULTIBYTE (tem))
+       tem = (code_convert_string_norecord
+              (tem, XPROCESS (proc)->encode_coding_system, 1));
+      new_argv[i - 2] = XSTRING (tem)->data;
+    }
+  new_argv[i - 2] = 0;
+#endif /* not VMS */
+
   XPROCESS (proc)->decoding_buf = make_uninit_string (0);
   XPROCESS (proc)->decoding_carryover = make_number (0);
   XPROCESS (proc)->encoding_buf = make_uninit_string (0);
@@ -1281,18 +1249,14 @@ start_process_unwind (proc)
   return Qnil;
 }
 
-
-SIGTYPE
-create_process_1 (signo)
-     int signo;
+void
+create_process_1 (timer)
+     struct atimer *timer;
 {
-#if defined (USG) && !defined (POSIX_SIGNALS)
-  /* USG systems forget handlers when they are used;
-     must reestablish each time */
-  signal (signo, create_process_1);
-#endif /* USG */
+  /* Nothing to do.  */
 }
 
+
 #if 0  /* This doesn't work; see the note before sigchld_handler.  */
 #ifdef USG
 #ifdef SIGCHLD
@@ -1339,7 +1303,9 @@ create_process (process, new_argv, current_dir)
   /* Use volatile to protect variables from being clobbered by longjmp.  */
   volatile int forkin, forkout;
   volatile int pty_flag = 0;
+#ifndef USE_CRT_DLL
   extern char **environ;
+#endif
   Lisp_Object buffer = XPROCESS (process)->buffer;
 
   inchannel = outchannel = -1;
@@ -1444,46 +1410,6 @@ create_process (process, new_argv, current_dir)
   setup_coding_system (XPROCESS (process)->encode_coding_system,
                       proc_encode_coding_system[outchannel]);
 
-  if ((!NILP (buffer) && NILP (XBUFFER (buffer)->enable_multibyte_characters))
-      || (NILP (buffer) && NILP (buffer_defaults.enable_multibyte_characters)))
-    {
-      /* 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 (XPROCESS (process)->decode_coding_system))
-       setup_raw_text_coding_system (proc_decode_coding_system[inchannel]);
-      if (!NILP (XPROCESS (process)->encode_coding_system))
-       setup_raw_text_coding_system (proc_encode_coding_system[outchannel]);
-    }
-
-  if (CODING_REQUIRE_ENCODING (proc_encode_coding_system[outchannel]))
-    {
-      /* Here we encode arguments by the coding system used for
-        sending data to the process.  We don't support using
-        different coding systems for encoding arguments and for
-        encoding data sent to the process.  */
-      struct gcpro gcpro1;
-      int i = 1;
-      struct coding_system *coding = proc_encode_coding_system[outchannel];
-
-      coding->mode |= CODING_MODE_LAST_BLOCK;
-      GCPRO1 (process);
-      while (new_argv[i] != 0)
-       {
-         int len = strlen (new_argv[i]);
-         int size = encoding_buffer_size (coding, len);
-         unsigned char *buf = (unsigned char *) alloca (size);
-
-         encode_coding (coding, (unsigned char *)new_argv[i], buf, len, size);
-         buf[coding->produced] = 0;
-         /* We don't have to free new_argv[i] because it points to a
-             Lisp string given as an argument to `start-process'.  */
-         new_argv[i++] = (char *) buf;
-       }
-      UNGCPRO;
-      coding->mode &= ~CODING_MODE_LAST_BLOCK;
-    }
-
   /* Delay interrupts until we have a chance to store
      the new fork's pid in its process structure */
 #ifdef POSIX_SIGNALS
@@ -1729,14 +1655,22 @@ create_process (process, new_argv, current_dir)
       /* If the subfork execv fails, and it exits,
         this close hangs.  I don't know why.
         So have an interrupt jar it loose.  */
-      stop_polling ();
-      signal (SIGALRM, create_process_1);
-      alarm (1);
-      XPROCESS (process)->subtty = Qnil;
-      if (forkin >= 0)
-       emacs_close (forkin);
-      alarm (0);
-      start_polling ();
+      {
+       struct atimer *timer;
+       EMACS_TIME offset;
+       
+       stop_polling ();
+       EMACS_SET_SECS_USECS (offset, 1, 0);
+       timer = start_atimer (ATIMER_RELATIVE, offset, create_process_1, 0);
+       
+       XPROCESS (process)->subtty = Qnil;
+       if (forkin >= 0)
+         emacs_close (forkin);
+
+       cancel_atimer (timer);
+       start_polling ();
+      }
+      
       if (forkin != forkout && forkout >= 0)
        emacs_close (forkout);
 
@@ -1814,18 +1748,18 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\
       Lisp_Object name, buffer, host, service;
 {
   Lisp_Object proc;
-#ifndef HAVE_GETADDRINFO
+#ifdef HAVE_GETADDRINFO
+  struct addrinfo hints, *res, *lres;
+  int ret = 0;
+  int xerrno = 0;
+  char *portstring, portbuf[128];
+#else /* 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 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;
@@ -1843,13 +1777,11 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\
   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.
-   */
+  /* 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));
+      sprintf (portbuf, "%ld", (long) XINT (service));
       portstring = portbuf;
     }
   else
@@ -1857,7 +1789,7 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\
       CHECK_STRING (service, 0);
       portstring = XSTRING (service)->data;
     }
-#else /* HAVE_GETADDRINFO */
+#else /* HAVE_GETADDRINFO */
   if (INTEGERP (service))
     port = htons ((unsigned short) XINT (service));
   else
@@ -1868,44 +1800,48 @@ 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 */
+#endif /* HAVE_GETADDRINFO */
 
 
   /* Slow down polling to every ten seconds.
      Some kernels have a bug which causes retrying connect to fail
      after a connect.  Polling can interfere with gethostbyname too.  */
 #ifdef POLL_FOR_INPUT
+  record_unwind_protect (unwind_stop_other_atimers, Qnil);
   bind_polling_period (10);
 #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,
-              strerror (ret));
-      }
-    immediate_quit = 0;
-  }
+  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)
+#ifdef HAVE_GAI_STRERROR
+    error ("%s/%s %s", XSTRING (host)->data, portstring, gai_strerror(ret));
+#else
+    error ("%s/%s getaddrinfo error %d", XSTRING (host)->data, portstring,
+          ret);
+#endif
+  immediate_quit = 0;
 
-  s = -1;
+  /* Do this in case we never enter the for-loop below.  */
   count1 = specpdl_ptr - specpdl;
-  record_unwind_protect (close_file_unwind, make_number (s));
+  s = -1;
 
   for (lres = res; lres; lres = lres->ai_next)
     {
       s = socket (lres->ai_family, lres->ai_socktype, lres->ai_protocol);
-      if (s < 0) 
-       continue;
+      if (s < 0)
+       {
+         xerrno = errno;
+         continue;
+       }
 
       /* Kernel bugs (on Ultrix at least) cause lossage (not just EINTR)
         when connect is interrupted.  So let's not let it get interrupted.
@@ -1916,12 +1852,50 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\
       if (interrupt_input)
        unrequest_sigio ();
 
+      /* Make us close S if quit.  */
+      count1 = specpdl_ptr - specpdl;
+      record_unwind_protect (close_file_unwind, make_number (s));
+
+    loop:
+
       immediate_quit = 1;
       QUIT;
 
+      /* This turns off all alarm-based interrupts; the
+        bind_polling_period call above doesn't always turn all the
+        short-interval ones off, especially if interrupt_input is
+        set.
+
+        It'd be nice to be able to control the connect timeout
+        though.  Would non-blocking connect calls be portable?  */
+      turn_on_atimers (0);
       ret = connect (s, lres->ai_addr, lres->ai_addrlen);
-      if (ret == 0)
+      xerrno = errno;
+      turn_on_atimers (1);
+
+      if (ret == 0 || xerrno == EISCONN)
+       /* The unwind-protect will be discarded afterwards.
+          Likewise for immediate_quit.  */
        break;
+
+      immediate_quit = 0;
+
+      if (xerrno == EINTR)
+       goto loop;
+      if (xerrno == EADDRINUSE && retry < 20)
+       {
+         /* A delay here is needed on some FreeBSD systems,
+            and it is harmless, since this retrying takes time anyway
+            and should be infrequent.  */
+         Fsleep_for (make_number (1), Qnil);
+         retry++;
+         goto loop;
+       }
+
+      /* Discard the unwind protect closing S.  */
+      specpdl_ptr = specpdl + count1;
+      count1 = specpdl_ptr - specpdl;
+      
       emacs_close (s);
       s = -1;
     }
@@ -1936,7 +1910,8 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\
       report_file_error ("connection failed",
                         Fcons (host, Fcons (name, Qnil)));
     }
-#else /* ! HAVE_GETADDRINFO */
+  
+#else /* not HAVE_GETADDRINFO */
 
   while (1)
     {
@@ -1957,6 +1932,7 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\
        break;
       Fsleep_for (make_number (1), Qnil);
     }
+  
   if (host_info_ptr == 0)
     /* Attempt to interpret host as numeric inet address */
     {
@@ -2038,11 +2014,12 @@ 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 */
+  
+#endif /* not HAVE_GETADDRINFO */
 
   immediate_quit = 0;
 
-  /* Discard the unwind protect.  */
+  /* Discard the unwind protect, if any.  */
   specpdl_ptr = specpdl + count1;
 
 #ifdef POLL_FOR_INPUT
@@ -2413,18 +2390,13 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
      Causes "poll: interrupted system call" messages when Emacs is run
      in an X window
      Turn off periodic alarms (in case they are in use) */
-  stop_polling ();
+  turn_on_atimers (0);
 #endif
 
   while (1)
     {
       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.  */
@@ -2848,12 +2820,6 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
   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;
 }
 \f
@@ -2874,6 +2840,7 @@ read_process_output_error_handler (error)
   Vinhibit_quit = Qt;
   update_echo_area ();
   Fsleep_for (make_number (2), Qnil);
+  return Qt;
 }
 
 /* Read pending output from the process channel,
@@ -2894,18 +2861,11 @@ read_process_output (proc, channel)
 {
   register int nchars, nbytes;
   char *chars;
-#ifdef VMS
-  int chars_allocated = 0;     /* If 1, `chars' should be freed later.  */
-#else
-  char buf[1024];
-#endif
   register Lisp_Object outstream;
   register struct buffer *old = current_buffer;
   register struct Lisp_Process *p = XPROCESS (proc);
   register int opoint;
   struct coding_system *coding = proc_decode_coding_system[channel];
-  int chars_in_decoding_buf = 0; /* If 1, `chars' points
-                                   XSTRING (p->decoding_buf)->data.  */
   int carryover = XINT (p->decoding_carryover);
 
 #ifdef VMS
@@ -2933,42 +2893,33 @@ read_process_output (proc, channel)
       /* The data carried over in the previous decoding (which are at
          the tail of decoding buffer) should be prepended to the new
          data read to decode all together.  */
-      char *buf = (char *) xmalloc (nbytes + carryover);
-
-      bcopy (XSTRING (p->decoding_buf)->data
-            + STRING_BYTES (XSTRING (p->decoding_buf)) - carryover,
-            buf, carryover);
-      bcopy (chars, buf + carryover, nbytes);
-      chars = buf;
-      chars_allocated = 1;
+      chars = (char *) alloca (nbytes + carryover);
+      bcopy (XSTRING (p->decoding_buf)->data, buf, carryover);
+      bcopy (vs->inputBuffer, chars + carryover, nbytes);
     }
 #else /* not VMS */
-
+  chars = (char *) alloca (carryover + 1024);
   if (carryover)
     /* See the comment above.  */
-    bcopy (XSTRING (p->decoding_buf)->data
-          + STRING_BYTES (XSTRING (p->decoding_buf)) - carryover,
-          buf, carryover);
+    bcopy (XSTRING (p->decoding_buf)->data, chars, carryover);
 
   if (proc_buffered_char[channel] < 0)
-    nbytes = emacs_read (channel, buf + carryover, (sizeof buf) - carryover);
+    nbytes = emacs_read (channel, chars + carryover, 1024 - carryover);
   else
     {
-      buf[carryover] = proc_buffered_char[channel];
+      chars[carryover] = proc_buffered_char[channel];
       proc_buffered_char[channel] = -1;
-      nbytes = emacs_read (channel, buf + carryover + 1,
-                          (sizeof buf) - carryover - 1);
+      nbytes = emacs_read (channel, chars + carryover + 1,  1023 - carryover);
       if (nbytes < 0)
        nbytes = 1;
       else
        nbytes = nbytes + 1;
     }
-  chars = buf;
 #endif /* not VMS */
 
   XSETINT (p->decoding_carryover, 0);
 
-  /* At this point, NBYTES holds number of characters just received
+  /* At this point, NBYTES holds number of bytes just received
      (including the one in proc_buffered_char[channel]).  */
   if (nbytes <= 0)
     {
@@ -2979,109 +2930,6 @@ read_process_output (proc, channel)
 
   /* Now set NBYTES how many bytes we must decode.  */
   nbytes += carryover;
-  nchars = nbytes;
-
-  if (CODING_MAY_REQUIRE_DECODING (coding))
-    {
-      int require = decoding_buffer_size (coding, nbytes);
-      int result;
-      
-      if (STRING_BYTES (XSTRING (p->decoding_buf)) < require)
-       p->decoding_buf = make_uninit_string (require);
-      result = decode_coding (coding, chars, XSTRING (p->decoding_buf)->data,
-                             nbytes, STRING_BYTES (XSTRING (p->decoding_buf)));
-      carryover = nbytes - coding->consumed;
-      if (carryover > 0)
-       {
-         /* Copy the carryover bytes to the end of p->decoding_buf, to
-            be processed on the next read.  Since decoding_buffer_size
-            asks for an extra amount of space beyond the maximum
-            expected for the output, there should always be sufficient
-            space for the carryover (which is by definition a sequence
-            of bytes that was not long enough to be decoded, and thus
-            has a bounded length).  */
-         if (STRING_BYTES (XSTRING (p->decoding_buf))
-             < coding->produced + carryover)
-           abort ();
-         bcopy (chars + coding->consumed,
-                XSTRING (p->decoding_buf)->data
-                + STRING_BYTES (XSTRING (p->decoding_buf)) - carryover,
-                carryover);
-         XSETINT (p->decoding_carryover, carryover);
-       }
-
-      /* A new coding system might be found by `decode_coding'.  */
-      if (!EQ (p->decode_coding_system, coding->symbol))
-       {
-         p->decode_coding_system = coding->symbol;
-
-         /* Don't call setup_coding_system for
-             proc_decode_coding_system[channel] here.  It is done in
-             detect_coding called via decode_coding above.  */
-
-         /* If a coding system for encoding is not yet decided, we set
-            it as the same as coding-system for decoding.
-
-            But, before doing that we must check if
-            proc_encode_coding_system[p->outfd] surely points to a
-            valid memory because p->outfd will be changed once EOF is
-            sent to the process.  */
-         if (NILP (p->encode_coding_system)
-             && proc_encode_coding_system[XINT (p->outfd)])
-           {
-             p->encode_coding_system = coding->symbol;
-             setup_coding_system (coding->symbol,
-                                  proc_encode_coding_system[XINT (p->outfd)]);
-           }
-       }
-
-#ifdef VMS
-      /*  Now we don't need the contents of `chars'.  */
-      if (chars_allocated)
-       free (chars);
-#endif
-      if (coding->produced == 0)
-       return 0;
-      chars = (char *) XSTRING (p->decoding_buf)->data;
-      nbytes = coding->produced;
-      nchars = (coding->fake_multibyte
-               ? multibyte_chars_in_text (chars, nbytes)
-               : coding->produced_char);
-      chars_in_decoding_buf = 1;
-    }
-  else
-    {
-#ifdef VMS
-      if (chars_allocated)
-       {
-         /* Although we don't have to decode the received data, we
-            must move it to an area which we don't have to free.  */
-         if (! STRINGP (p->decoding_buf)
-             || STRING_BYTES (XSTRING (p->decoding_buf)) < nbytes)
-           p->decoding_buf = make_uninit_string (nbytes);
-         bcopy (chars, XSTRING (p->decoding_buf)->data, nbytes);
-         free (chars);
-         chars = XSTRING (p->decoding_buf)->data;
-         chars_in_decoding_buf = 1;
-       }
-#endif
-      nchars = multibyte_chars_in_text (chars, nbytes);
-    }
-
-  Vlast_coding_system_used = coding->symbol;
-
-  /* If the caller required, let the process associated buffer
-     inherit the coding-system used to decode the process output.  */
-  if (! NILP (p->inherit_coding_system_flag)
-      && !NILP (p->buffer) && !NILP (XBUFFER (p->buffer)->name))
-    {
-      struct buffer *prev_buf = current_buffer;
-
-      Fset_buffer (p->buffer);
-      call1 (intern ("after-insert-file-set-buffer-file-coding-system"),
-            make_number (nbytes));
-      set_buffer_internal (prev_buf);
-    }
 
   /* Read and dispose of the process output.  */
   outstream = p->filter;
@@ -3123,14 +2971,44 @@ read_process_output (proc, channel)
         save the match data in a special nonrecursive fashion.  */
       running_asynch_code = 1;
 
-      /* 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);
+      text = decode_coding_string (make_unibyte_string (chars, nbytes),
+                                  coding, 0);
+      if (NILP (buffer_defaults.enable_multibyte_characters))
+       /* We had better return unibyte string.  */
+       text = string_make_unibyte (text);
+
+      Vlast_coding_system_used = coding->symbol;
+      /* A new coding system might be found.  */
+      if (!EQ (p->decode_coding_system, coding->symbol))
+       {
+         p->decode_coding_system = coding->symbol;
+
+         /* Don't call setup_coding_system for
+            proc_decode_coding_system[channel] here.  It is done in
+            detect_coding called via decode_coding above.  */
+
+         /* If a coding system for encoding is not yet decided, we set
+            it as the same as coding-system for decoding.
 
+            But, before doing that we must check if
+            proc_encode_coding_system[p->outfd] surely points to a
+            valid memory because p->outfd will be changed once EOF is
+            sent to the process.  */
+         if (NILP (p->encode_coding_system)
+             && proc_encode_coding_system[XINT (p->outfd)])
+           {
+             p->encode_coding_system = coding->symbol;
+             setup_coding_system (coding->symbol,
+                                  proc_encode_coding_system[XINT (p->outfd)]);
+           }
+       }
+
+      carryover = nbytes - coding->consumed;
+      bcopy (chars + coding->consumed, XSTRING (p->decoding_buf)->data,
+            carryover);
+      XSETINT (p->decoding_carryover, carryover);
+      nbytes = STRING_BYTES (XSTRING (text));
+      nchars = XSTRING (text)->size;
       internal_condition_case_1 (read_process_output_call,
                                 Fcons (outstream,
                                        Fcons (proc, Fcons (text, Qnil))),
@@ -3176,6 +3054,7 @@ read_process_output (proc, channel)
       Lisp_Object odeactivate;
       int before, before_byte;
       int opoint_byte;
+      Lisp_Object text;
 
       odeactivate = Vdeactivate_mark;
 
@@ -3207,26 +3086,40 @@ read_process_output (proc, channel)
       if (! (BEGV <= PT && PT <= ZV))
        Fwiden ();
 
-      if (NILP (current_buffer->enable_multibyte_characters))
-       nchars = nbytes;
-
+      text = decode_coding_string (make_unibyte_string (chars, nbytes),
+                                  coding, 0);
+      Vlast_coding_system_used = coding->symbol;
+      /* A new coding system might be found.  See the comment in the
+        similar code in the previous `if' block.  */
+      if (!EQ (p->decode_coding_system, coding->symbol))
+       {
+         p->decode_coding_system = coding->symbol;
+         if (NILP (p->encode_coding_system)
+             && proc_encode_coding_system[XINT (p->outfd)])
+           {
+             p->encode_coding_system = coding->symbol;
+             setup_coding_system (coding->symbol,
+                                  proc_encode_coding_system[XINT (p->outfd)]);
+           }
+       }
+      carryover = nbytes - coding->consumed;
+      bcopy (chars + coding->consumed, XSTRING (p->decoding_buf)->data,
+            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))
+       text = (STRING_MULTIBYTE (text)
+               ? Fstring_as_unibyte (text)
+               : Fstring_as_multibyte (text));
+      nbytes = STRING_BYTES (XSTRING (text));
+      nchars = XSTRING (text)->size;
       /* Insert before markers in case we are inserting where
         the buffer's mark is, and the user's next command is Meta-y.  */
-      if (chars_in_decoding_buf)
-       {
-         /* Since multibyteness of p->docoding_buf is corrupted, we
-             can't use insert_from_string_before_markers.  */
-         char *temp_buf;
+      insert_from_string_before_markers (text, 0, 0, nchars, nbytes, 0);
+      signal_after_change (before, 0, PT - before);
+      update_compositions (before, PT, CHECK_BORDER);
 
-         temp_buf = (char *) alloca (nbytes);
-         bcopy (XSTRING (p->decoding_buf)->data, temp_buf, nbytes);
-         insert_before_markers (temp_buf, nbytes);
-       }
-      else
-       {
-         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++;
@@ -3278,6 +3171,7 @@ This is intended for use by asynchronous process output filters and sentinels.")
 /* Sending data to subprocess */
 
 jmp_buf send_process_frame;
+Lisp_Object process_sent_to;
 
 SIGTYPE
 send_process_trap ()
@@ -3291,27 +3185,25 @@ send_process_trap ()
 
 /* Send some data to process PROC.
    BUF is the beginning of the data; LEN is the number of characters.
-   OBJECT is the Lisp object that the data comes from.
+   OBJECT is the Lisp object that the data comes from.  If OBJECT is
+   nil or t, it means that the data comes from C string.
+
+   If OBJECT is not nil, the data is encoded by PROC's coding-system
+   for encoding before it is sent.
 
-   The data is encoded by PROC's coding-system for encoding before it
-   is sent.  But if the data ends at the middle of multi-byte
-   representation, that incomplete sequence of bytes are sent without
-   being encoded.  Should we store them in a buffer to prepend them to
-   the data send later?  */
+   This function can evaluate Lisp code and can garbage collect.  */
 
 void
 send_process (proc, buf, len, object)
      volatile Lisp_Object proc;
-     unsigned char *buf;
-     int len;
-     Lisp_Object object;
+     unsigned char *volatile buf;
+     volatile int len;
+     volatile Lisp_Object object;
 {
   /* Use volatile to protect variables from being clobbered by longjmp.  */
   int rv;
-  volatile unsigned char *procname = XSTRING (XPROCESS (proc)->name)->data;
   struct coding_system *coding;
   struct gcpro gcpro1;
-  int carryover = XINT (XPROCESS (proc)->encoding_carryover);
 
   GCPRO1 (object);
 
@@ -3323,64 +3215,81 @@ send_process (proc, buf, len, object)
   if (! NILP (XPROCESS (proc)->raw_status_low))
     update_status (XPROCESS (proc));
   if (! EQ (XPROCESS (proc)->status, Qrun))
-    error ("Process %s not running", procname);
+    error ("Process %s not running",
+          XSTRING (XPROCESS (proc)->name)->data);
   if (XINT (XPROCESS (proc)->outfd) < 0)
-    error ("Output file descriptor of %s is closed", procname);
+    error ("Output file descriptor of %s is closed",
+          XSTRING (XPROCESS (proc)->name)->data);
 
   coding = proc_encode_coding_system[XINT (XPROCESS (proc)->outfd)];
   Vlast_coding_system_used = coding->symbol;
 
+  if ((STRINGP (object) && STRING_MULTIBYTE (object))
+      || (BUFFERP (object)
+         && !NILP (XBUFFER (object)->enable_multibyte_characters))
+      || EQ (object, Qt))
+    {
+      coding->src_multibyte = 1;
+      if (!EQ (coding->symbol, XPROCESS (proc)->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 (XPROCESS (proc)->encode_coding_system,
+                            coding);
+    }
+  else
+    {
+      /* For sending a unibyte text, character code conversion should
+        not take place but EOL conversion should.  So, setup raw-text
+        or one of the subsidiary if we have not yet done it.  */
+      if (coding->type != coding_type_raw_text)
+       {
+         if (CODING_REQUIRE_FLUSHING (coding))
+           {
+             /* But, before changing the coding, we must flush out data.  */
+             coding->mode |= CODING_MODE_LAST_BLOCK;
+             send_process (proc, "", 0, Qt);
+           }
+         coding->src_multibyte = 0;
+         setup_raw_text_coding_system (coding);
+       }
+    }
+  coding->dst_multibyte = 0;
+
   if (CODING_REQUIRE_ENCODING (coding))
     {
       int require = encoding_buffer_size (coding, len);
-      int offset;
+      int from_byte = -1, from = -1, to = -1;
       unsigned char *temp_buf = NULL;
 
-      /* 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 about relocation.  */
-      offset = (BUFFERP (object)
-               ? BUF_PTR_BYTE_POS (XBUFFER (object), buf)
-               : (STRINGP (object)
-                  ? buf - XSTRING (object)->data
-                  : -1));
-
-      if (carryover > 0)
+      if (BUFFERP (object))
        {
-         temp_buf = (unsigned char *) xmalloc (len + carryover);
-
-         if (offset >= 0)
-           {
-             if (BUFFERP (object))
-               buf = BUF_BYTE_ADDRESS (XBUFFER (object), offset);
-             else if (STRINGP (object))
-               buf = offset + XSTRING (object)->data;
-             /* Now we don't have to care about relocation.  */
-             offset = -1;
-           }
-         bcopy ((XSTRING (XPROCESS (proc)->encoding_buf)->data
-                 + STRING_BYTES (XSTRING (XPROCESS (proc)->encoding_buf))
-                 - carryover),
-                temp_buf,
-                carryover);
-         bcopy (buf, temp_buf + carryover, len);
-         buf = temp_buf;
+         from_byte = BUF_PTR_BYTE_POS (XBUFFER (object), buf);
+         from = buf_bytepos_to_charpos (XBUFFER (object), from_byte);
+         to = buf_bytepos_to_charpos (XBUFFER (object), from_byte + len);
        }
+      else if (STRINGP (object))
+       {
+         from_byte = buf - XSTRING (object)->data;
+         from = string_byte_to_char (object, from_byte);
+         to =  string_byte_to_char (object, from_byte + len);
+       }
+
+      if (from_byte >= 0 && coding->composing != COMPOSITION_DISABLED)
+       coding_save_composition (coding, from, to, object);
 
       if (STRING_BYTES (XSTRING (XPROCESS (proc)->encoding_buf)) < require)
-       {
-         XPROCESS (proc)->encoding_buf = make_uninit_string (require);
+       XPROCESS (proc)->encoding_buf = make_uninit_string (require);
+
+      if (from_byte >= 0)
+       buf = (BUFFERP (object)
+              ? BUF_BYTE_ADDRESS (XBUFFER (object), from_byte)
+              : XSTRING (object)->data + from_byte);
 
-         if (offset >= 0)
-           {
-             if (BUFFERP (object))
-               buf = BUF_BYTE_ADDRESS (XBUFFER (object), offset);
-             else if (STRINGP (object))
-               buf = offset + XSTRING (object)->data;
-           }
-       }
       object = XPROCESS (proc)->encoding_buf;
-      encode_coding (coding, buf, XSTRING (object)->data,
+      encode_coding (coding, (char *) buf, XSTRING (object)->data,
                     len, STRING_BYTES (XSTRING (object)));
       len = coding->produced;
       buf = XSTRING (object)->data;
@@ -3394,7 +3303,7 @@ send_process (proc, buf, len, object)
     error ("Could not find this process: %x", p->pid);
   else if (write_to_vms_process (vs, buf, len))
     ;
-#else
+#else /* not VMS */
 
   if (pty_max_bytes == 0)
     {
@@ -3410,111 +3319,149 @@ send_process (proc, buf, len, object)
       pty_max_bytes--;
     }
 
+  /* 2000-09-21: Emacs 20.7, sparc-sun-solaris-2.6, GCC 2.95.2,
+     CFLAGS="-g -O": The value of the parameter `proc' is clobbered
+     when returning with longjmp despite being declared volatile.  */
   if (!setjmp (send_process_frame))
-    while (len > 0)
-      {
-       int this = len;
-       SIGTYPE (*old_sigpipe)();
+    {
+      process_sent_to = proc;
+      while (len > 0)
+       {
+         int this = len;
+         SIGTYPE (*old_sigpipe)();
 
-       /* Decide how much data we can send in one batch.
-          Long lines need to be split into multiple batches.  */
-       if (!NILP (XPROCESS (proc)->pty_flag))
-         {
-           /* Starting this at zero is always correct when not the first iteration
-              because the previous iteration ended by sending C-d.
-              It may not be correct for the first iteration
-              if a partial line was sent in a separate send_process call.
-              If that proves worth handling, we need to save linepos
-              in the process object.  */
-           int linepos = 0;
-           unsigned char *ptr = buf;
-           unsigned char *end = buf + len;
-
-           /* Scan through this text for a line that is too long.  */
-           while (ptr != end && linepos < pty_max_bytes)
-             {
-               if (*ptr == '\n')
-                 linepos = 0;
-               else
-                 linepos++;
-               ptr++;
-             }
-           /* If we found one, break the line there
-              and put in a C-d to force the buffer through.  */
-           this = ptr - buf;
-         }
+         /* Decide how much data we can send in one batch.
+            Long lines need to be split into multiple batches.  */
+         if (!NILP (XPROCESS (proc)->pty_flag))
+           {
+             /* Starting this at zero is always correct when not the first iteration
+                because the previous iteration ended by sending C-d.
+                It may not be correct for the first iteration
+                if a partial line was sent in a separate send_process call.
+                If that proves worth handling, we need to save linepos
+                in the process object.  */
+             int linepos = 0;
+             unsigned char *ptr = (unsigned char *) buf;
+             unsigned char *end = (unsigned char *) buf + len;
+
+             /* Scan through this text for a line that is too long.  */
+             while (ptr != end && linepos < pty_max_bytes)
+               {
+                 if (*ptr == '\n')
+                   linepos = 0;
+                 else
+                   linepos++;
+                 ptr++;
+               }
+             /* If we found one, break the line there
+                and put in a C-d to force the buffer through.  */
+             this = ptr - buf;
+           }
 
-       /* Send this batch, using one or more write calls.  */
-       while (this > 0)
-         {
-           old_sigpipe = (SIGTYPE (*) ()) signal (SIGPIPE, send_process_trap);
-           rv = emacs_write (XINT (XPROCESS (proc)->outfd), buf, this);
-           signal (SIGPIPE, old_sigpipe);
+         /* Send this batch, using one or more write calls.  */
+         while (this > 0)
+           {
+             old_sigpipe = (SIGTYPE (*) ()) signal (SIGPIPE, send_process_trap);
+             rv = emacs_write (XINT (XPROCESS (proc)->outfd),
+                               (char *) buf, this);
+             signal (SIGPIPE, old_sigpipe);
 
-           if (rv < 0)
-             {
-               if (0
+             if (rv < 0)
+               {
+                 if (0
 #ifdef EWOULDBLOCK
-                   || errno == EWOULDBLOCK
+                     || errno == EWOULDBLOCK
 #endif
 #ifdef EAGAIN
-                   || errno == EAGAIN
+                     || errno == EAGAIN
 #endif
-                   )
-                 /* Buffer is full.  Wait, accepting input; 
-                    that may allow the program
-                    to finish doing output and read more.  */
-                 {
-                   Lisp_Object zero;
-                   int offset;
-
-                   /* Running filters might relocate buffers or strings.
-                      Arrange to relocate BUF.  */
-                   if (BUFFERP (object))
-                     offset = BUF_PTR_BYTE_POS (XBUFFER (object), buf);
-                   else if (STRINGP (object))
-                     offset = buf - XSTRING (object)->data;
-
-                   XSETFASTINT (zero, 0);
+                     )
+                   /* Buffer is full.  Wait, accepting input; 
+                      that may allow the program
+                      to finish doing output and read more.  */
+                   {
+                     Lisp_Object zero;
+                     int offset = 0;
+
+#ifdef BROKEN_PTY_READ_AFTER_EAGAIN
+                     /* A gross hack to work around a bug in FreeBSD.
+                        In the following sequence, read(2) returns
+                        bogus data:
+
+                        write(2)        1022 bytes
+                        write(2)   954 bytes, get EAGAIN
+                        read(2)   1024 bytes in process_read_output
+                        read(2)     11 bytes in process_read_output
+
+                        That is, read(2) returns more bytes than have
+                        ever been written successfully.  The 1033 bytes
+                        read are the 1022 bytes written successfully
+                        after processing (for example with CRs added if
+                        the terminal is set up that way which it is
+                        here).  The same bytes will be seen again in a
+                        later read(2), without the CRs.  */
+                   
+                     if (errno == EAGAIN)
+                       {
+                         int flags = FWRITE;
+                         ioctl (XINT (XPROCESS (proc)->outfd), TIOCFLUSH,
+                                &flags);
+                       }
+#endif /* BROKEN_PTY_READ_AFTER_EAGAIN */
+                   
+                     /* Running filters might relocate buffers or strings.
+                        Arrange to relocate BUF.  */
+                     if (BUFFERP (object))
+                       offset = BUF_PTR_BYTE_POS (XBUFFER (object), buf);
+                     else if (STRINGP (object))
+                       offset = buf - XSTRING (object)->data;
+
+                     XSETFASTINT (zero, 0);
 #ifdef EMACS_HAS_USECS
-                   wait_reading_process_input (0, 20000, zero, 0);
+                     wait_reading_process_input (0, 20000, zero, 0);
 #else
-                   wait_reading_process_input (1, 0, zero, 0);
+                     wait_reading_process_input (1, 0, zero, 0);
 #endif
 
-                   if (BUFFERP (object))
-                     buf = BUF_BYTE_ADDRESS (XBUFFER (object), offset);
-                   else if (STRINGP (object))
-                     buf = offset + XSTRING (object)->data;
+                     if (BUFFERP (object))
+                       buf = BUF_BYTE_ADDRESS (XBUFFER (object), offset);
+                     else if (STRINGP (object))
+                       buf = offset + XSTRING (object)->data;
 
-                   rv = 0;
-                 }
-               else
-                 /* This is a real error.  */
-                 report_file_error ("writing to process", Fcons (proc, Qnil));
-             }
-           buf += rv;
-           len -= rv;
-           this -= rv;
-         }
+                     rv = 0;
+                   }
+                 else
+                   /* This is a real error.  */
+                   report_file_error ("writing to process", Fcons (proc, Qnil));
+               }
+             buf += rv;
+             len -= rv;
+             this -= rv;
+           }
 
-       /* If we sent just part of the string, put in an EOF
-          to force it through, before we send the rest.  */
-       if (len > 0)
-         Fprocess_send_eof (proc);
-      }
-#endif
+         /* If we sent just part of the string, put in an EOF
+            to force it through, before we send the rest.  */
+         if (len > 0)
+           Fprocess_send_eof (proc);
+       }
+    }
+#endif /* not VMS */
   else
     {
+#ifndef VMS
+      proc = process_sent_to;
+#endif
       XPROCESS (proc)->raw_status_low = Qnil;
       XPROCESS (proc)->raw_status_high = Qnil;
       XPROCESS (proc)->status = Fcons (Qexit, Fcons (make_number (256), Qnil));
       XSETINT (XPROCESS (proc)->tick, ++process_tick);
       deactivate_process (proc);
 #ifdef VMS
-      error ("Error writing to process %s; closed it", procname);
+      error ("Error writing to process %s; closed it", 
+            XSTRING (XPROCESS (proc)->name)->data);
 #else
-      error ("SIGPIPE raised on process %s; closed it", procname);
+      error ("SIGPIPE raised on process %s; closed it",
+            XSTRING (XPROCESS (proc)->name)->data);
 #endif
     }
 
@@ -4254,7 +4201,7 @@ sigchld_handler (signo)
              int code = WTERMSIG (w);
              char *signame;
 
-             synchronize_messages_locale ();
+             synchronize_system_messages_locale ();
              signame = strsignal (code);
 
              if (signame == 0)
@@ -4301,6 +4248,7 @@ exec_sentinel_error_handler (error)
   Vinhibit_quit = Qt;
   update_echo_area ();
   Fsleep_for (make_number (2), Qnil);
+  return Qt;
 }
 
 static void
@@ -4623,11 +4571,6 @@ init_process ()
     }
   bzero (proc_decode_coding_system, sizeof proc_decode_coding_system);
   bzero (proc_encode_coding_system, sizeof proc_encode_coding_system);
-
-  Vdefault_process_coding_system
-    = (NILP (buffer_defaults.enable_multibyte_characters)
-       ? Fcons (Qraw_text, Qnil)
-       : Fcons (Qemacs_mule, Qnil));
 }
 
 void
@@ -4788,7 +4731,7 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
 
   /* Turn off periodic alarms (in case they are in use)
      because the select emulator uses alarms.  */
-  stop_polling ();
+  turn_on_atimers (0);
 
   while (1)
     {