(Fstart_process): Use raw-text instead of emacs-mule
[bpt/emacs.git] / src / process.c
index f8a8445..59bb8e3 100644 (file)
@@ -1,5 +1,5 @@
 /* Asynchronous subprocess control for GNU Emacs.
 /* Asynchronous subprocess control for GNU Emacs.
-   Copyright (C) 1985, 86, 87, 88, 93, 94, 95, 1996
+   Copyright (C) 1985, 86, 87, 88, 93, 94, 95, 96, 1998
       Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
       Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -266,6 +266,8 @@ extern int timers_run;
 /* Maximum number of bytes to send to a pty without an eof.  */
 static int pty_max_bytes;
 
 /* Maximum number of bytes to send to a pty without an eof.  */
 static int pty_max_bytes;
 
+extern Lisp_Object Vfile_name_coding_system;
+
 #ifdef HAVE_PTYS
 /* The file name of the pty opened by allocate_pty.  */
 
 #ifdef HAVE_PTYS
 /* The file name of the pty opened by allocate_pty.  */
 
@@ -1087,12 +1089,12 @@ Remaining arguments are strings to give program as arguments.")
 #ifdef VMS
   /* Make a one member argv with all args concatenated
      together separated by a blank.  */
 #ifdef VMS
   /* Make a one member argv with all args concatenated
      together separated by a blank.  */
-  len = XSTRING (program)->size + 2;
+  len = XSTRING (program)->size_byte + 2;
   for (i = 3; i < nargs; i++)
     {
       tem = args[i];
       CHECK_STRING (tem, i);
   for (i = 3; i < nargs; i++)
     {
       tem = args[i];
       CHECK_STRING (tem, i);
-      len += XSTRING (tem)->size + 1;  /* count the blank */
+      len += XSTRING (tem)->size_byte + 1;     /* count the blank */
     }
   new_argv = (unsigned char *) alloca (len);
   strcpy (new_argv, XSTRING (program)->data);
     }
   new_argv = (unsigned char *) alloca (len);
   strcpy (new_argv, XSTRING (program)->data);
@@ -1157,8 +1159,9 @@ Remaining arguments are strings to give program as arguments.")
 
   /* Make the process marker point into the process buffer (if any).  */
   if (!NILP (buffer))
 
   /* Make the process marker point into the process buffer (if any).  */
   if (!NILP (buffer))
-    Fset_marker (XPROCESS (proc)->mark,
-                make_number (BUF_ZV (XBUFFER (buffer))), buffer);
+    set_marker_both (XPROCESS (proc)->mark, buffer,
+                    BUF_ZV (XBUFFER (buffer)),
+                    BUF_ZV_BYTE (XBUFFER (buffer)));
 
   if (!NILP (buffer) && NILP (XBUFFER (buffer)->enable_multibyte_characters)
       || NILP (buffer) && NILP (buffer_defaults.enable_multibyte_characters))
 
   if (!NILP (buffer) && NILP (XBUFFER (buffer)->enable_multibyte_characters)
       || NILP (buffer) && NILP (buffer_defaults.enable_multibyte_characters))
@@ -1169,27 +1172,37 @@ Remaining arguments are strings to give program as arguments.")
   else
     {
       /* Setup coding systems for communicating with the process.  */
   else
     {
       /* Setup coding systems for communicating with the process.  */
-      /* Qt denotes that we have not yet called Ffind_coding_system.  */
+      /* Qt denotes we have not yet called Ffind_operation_coding_system.  */
       Lisp_Object coding_systems = Qt;
       Lisp_Object val, *args2;
       struct gcpro gcpro1;
 
       Lisp_Object coding_systems = Qt;
       Lisp_Object val, *args2;
       struct gcpro gcpro1;
 
-      if (NILP (val = Vcoding_system_for_read))
+      if (!NILP (Vcoding_system_for_read))
+       val = Vcoding_system_for_read;
+      else if (NILP (current_buffer->enable_multibyte_characters))
+       val = Qraw_text;
+      else
        {
          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);
        {
          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);
-         coding_systems = Ffind_coding_system (nargs + 1, args2);
+         coding_systems = Ffind_operation_coding_system (nargs + 1, args2);
          UNGCPRO;
          if (CONSP (coding_systems))
            val = XCONS (coding_systems)->car;
          else if (CONSP (Vdefault_process_coding_system))
            val = XCONS (Vdefault_process_coding_system)->car;
          UNGCPRO;
          if (CONSP (coding_systems))
            val = XCONS (coding_systems)->car;
          else if (CONSP (Vdefault_process_coding_system))
            val = XCONS (Vdefault_process_coding_system)->car;
+         else
+           val = Qnil;
        }
       XPROCESS (proc)->decode_coding_system = val;
 
        }
       XPROCESS (proc)->decode_coding_system = val;
 
-      if (NILP (val = Vcoding_system_for_write))
+      if (!NILP (Vcoding_system_for_write))
+       val = Vcoding_system_for_write;
+      else if (NILP (current_buffer->enable_multibyte_characters))
+       val = Qnil;
+      else
        {
          if (EQ (coding_systems, Qt))
            {
        {
          if (EQ (coding_systems, Qt))
            {
@@ -1197,21 +1210,26 @@ Remaining arguments are strings to give program as arguments.")
              args2[0] = Qstart_process;
              for (i = 0; i < nargs; i++) args2[i + 1] = args[i];
              GCPRO1 (proc);
              args2[0] = Qstart_process;
              for (i = 0; i < nargs; i++) args2[i + 1] = args[i];
              GCPRO1 (proc);
-             coding_systems = Ffind_coding_system (nargs + 1, args2);
+             coding_systems =
+               Ffind_operation_coding_system (nargs + 1, args2);
              UNGCPRO;
            }
          if (CONSP (coding_systems))
            val = XCONS (coding_systems)->cdr;
          else if (CONSP (Vdefault_process_coding_system))
            val = XCONS (Vdefault_process_coding_system)->cdr;
              UNGCPRO;
            }
          if (CONSP (coding_systems))
            val = XCONS (coding_systems)->cdr;
          else if (CONSP (Vdefault_process_coding_system))
            val = XCONS (Vdefault_process_coding_system)->cdr;
+         else
+           val = Qnil;
        }
       XPROCESS (proc)->encode_coding_system = val;
     }
 
   XPROCESS (proc)->decoding_buf = make_uninit_string (0);
        }
       XPROCESS (proc)->encode_coding_system = val;
     }
 
   XPROCESS (proc)->decoding_buf = make_uninit_string (0);
+  XPROCESS (proc)->decoding_carryover = make_number (0);
   XPROCESS (proc)->encoding_buf = make_uninit_string (0);
   XPROCESS (proc)->encoding_buf = make_uninit_string (0);
+  XPROCESS (proc)->encoding_carryover = make_number (0);
 
 
-  create_process (proc, new_argv, current_dir);
+  create_process (proc, (char **) new_argv, current_dir);
 
   return unbind_to (count, proc);
 }
 
   return unbind_to (count, proc);
 }
@@ -1266,6 +1284,7 @@ create_process_sigchld ()
 #endif
 
 #ifndef VMS /* VMS version of this function is in vmsproc.c.  */
 #endif
 
 #ifndef VMS /* VMS version of this function is in vmsproc.c.  */
+void
 create_process (process, new_argv, current_dir)
      Lisp_Object process;
      char **new_argv;
 create_process (process, new_argv, current_dir)
      Lisp_Object process;
      char **new_argv;
@@ -1384,6 +1403,34 @@ create_process (process, new_argv, current_dir)
   setup_coding_system (XPROCESS (process)->encode_coding_system,
                       proc_encode_coding_system[outchannel]);
 
   setup_coding_system (XPROCESS (process)->encode_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, 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++] = 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
   /* Delay interrupts until we have a chance to store
      the new fork's pid in its process structure */
 #ifdef POSIX_SIGNALS
@@ -1440,6 +1487,9 @@ create_process (process, new_argv, current_dir)
        Protect it from permanent change.  */
     char **save_environ = environ;
 
        Protect it from permanent change.  */
     char **save_environ = environ;
 
+    current_dir
+      = Fencode_coding_string (current_dir, Vfile_name_coding_system, Qt);
+
 #ifndef WINDOWSNT
     pid = vfork ();
     if (pid == 0)
 #ifndef WINDOWSNT
     pid = vfork ();
     if (pid == 0)
@@ -1902,38 +1952,54 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\
     {
       /* Setup coding systems for communicating with the network stream.  */
       struct gcpro gcpro1;
     {
       /* Setup coding systems for communicating with the network stream.  */
       struct gcpro gcpro1;
-      /* Qt denotes that we have not yet called Ffind_coding_system.  */
+      /* Qt denotes we have not yet called Ffind_operation_coding_system.  */
       Lisp_Object coding_systems = Qt;
       Lisp_Object args[5], val;
 
       Lisp_Object coding_systems = Qt;
       Lisp_Object args[5], val;
 
-      if (NILP (val = Vcoding_system_for_read))
+      if (!NILP (Vcoding_system_for_read))
+       val = Vcoding_system_for_read;
+      else if (NILP (current_buffer->enable_multibyte_characters))
+       /* We dare not decode end-of-line format by setting VAL to
+           Qraw_text, because the existing Emacs Lisp libraries
+           assume that they receive bare code including a sequene of
+           CR LF.  */
+       val = Qnil;
+      else
        {
          args[0] = Qopen_network_stream, args[1] = name,
            args[2] = buffer, args[3] = host, args[4] = service;
          GCPRO1 (proc);
        {
          args[0] = Qopen_network_stream, args[1] = name,
            args[2] = buffer, args[3] = host, args[4] = service;
          GCPRO1 (proc);
-         coding_systems = Ffind_coding_system (5, args);
+         coding_systems = Ffind_operation_coding_system (5, args);
          UNGCPRO;
          if (CONSP (coding_systems))
            val = XCONS (coding_systems)->car;
          else if (CONSP (Vdefault_process_coding_system))
            val = XCONS (Vdefault_process_coding_system)->car;
          UNGCPRO;
          if (CONSP (coding_systems))
            val = XCONS (coding_systems)->car;
          else if (CONSP (Vdefault_process_coding_system))
            val = XCONS (Vdefault_process_coding_system)->car;
+         else
+           val = Qnil;
        }
       XPROCESS (proc)->decode_coding_system = val;
 
        }
       XPROCESS (proc)->decode_coding_system = val;
 
-      if (NILP (val = Vcoding_system_for_write))
+      if (!NILP (Vcoding_system_for_write))
+       val = Vcoding_system_for_write;
+      else if (NILP (current_buffer->enable_multibyte_characters))
+       val = Qnil;
+      else
        {
          if (EQ (coding_systems, Qt))
            {
              args[0] = Qopen_network_stream, args[1] = name,
                args[2] = buffer, args[3] = host, args[4] = service;
              GCPRO1 (proc);
        {
          if (EQ (coding_systems, Qt))
            {
              args[0] = Qopen_network_stream, args[1] = name,
                args[2] = buffer, args[3] = host, args[4] = service;
              GCPRO1 (proc);
-             coding_systems = Ffind_coding_system (5, args);
+             coding_systems = Ffind_operation_coding_system (5, args);
              UNGCPRO;
            }
          if (CONSP (coding_systems))
            val = XCONS (coding_systems)->cdr;
          else if (CONSP (Vdefault_process_coding_system))
            val = XCONS (Vdefault_process_coding_system)->cdr;
              UNGCPRO;
            }
          if (CONSP (coding_systems))
            val = XCONS (coding_systems)->cdr;
          else if (CONSP (Vdefault_process_coding_system))
            val = XCONS (Vdefault_process_coding_system)->cdr;
+         else
+           val = Qnil;
        }
       XPROCESS (proc)->encode_coding_system = val;
     }
        }
       XPROCESS (proc)->encode_coding_system = val;
     }
@@ -1950,13 +2016,16 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\
                       proc_encode_coding_system[outch]);
 
   XPROCESS (proc)->decoding_buf = make_uninit_string (0);
                       proc_encode_coding_system[outch]);
 
   XPROCESS (proc)->decoding_buf = make_uninit_string (0);
+  XPROCESS (proc)->decoding_carryover = make_number (0);
   XPROCESS (proc)->encoding_buf = make_uninit_string (0);
   XPROCESS (proc)->encoding_buf = make_uninit_string (0);
+  XPROCESS (proc)->encoding_carryover = make_number (0);
 
   UNGCPRO;
   return proc;
 }
 #endif /* HAVE_SOCKETS */
 
 
   UNGCPRO;
   return proc;
 }
 #endif /* HAVE_SOCKETS */
 
+void
 deactivate_process (proc)
      Lisp_Object proc;
 {
 deactivate_process (proc)
      Lisp_Object proc;
 {
@@ -2006,6 +2075,7 @@ deactivate_process (proc)
    with subprocess.  This is used in a newly-forked subprocess
    to get rid of irrelevant descriptors.  */
 
    with subprocess.  This is used in a newly-forked subprocess
    to get rid of irrelevant descriptors.  */
 
+void
 close_process_descs ()
 {
 #ifndef WINDOWSNT
 close_process_descs ()
 {
 #ifndef WINDOWSNT
@@ -2308,7 +2378,7 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
       if (wait_proc != 0
          && ! EQ (wait_proc->status, Qrun))
        {
       if (wait_proc != 0
          && ! EQ (wait_proc->status, Qrun))
        {
-         int nread, total_nread;
+         int nread, total_nread = 0;
 
          clear_waiting_for_input ();
          XSETPROCESS (proc, wait_proc);
 
          clear_waiting_for_input ();
          XSETPROCESS (proc, wait_proc);
@@ -2317,7 +2387,14 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
          while (XINT (wait_proc->infd) >= 0
                 && (nread
                     = read_process_output (proc, XINT (wait_proc->infd))))
          while (XINT (wait_proc->infd) >= 0
                 && (nread
                     = read_process_output (proc, XINT (wait_proc->infd))))
-           total_nread += nread;
+           {
+              if (0 < nread) 
+                total_nread += nread;
+#ifdef EIO
+             else if (nread == -1 && EIO == errno)
+                break;
+#endif
+           }
          if (total_nread > 0 && do_display)
            redisplay_preserve_echo_area ();
 
          if (total_nread > 0 && do_display)
            redisplay_preserve_echo_area ();
 
@@ -2436,7 +2513,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 there is any, return immediately
         to give it higher priority than subprocesses */
 
-      if ((XINT (read_kbd) != 0)
+      if (XINT (read_kbd) != 0
          && detect_input_pending_run_timers (do_display))
        {
          swallow_events (do_display);
          && detect_input_pending_run_timers (do_display))
        {
          swallow_events (do_display);
@@ -2449,13 +2526,14 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
          && requeued_events_pending_p ())
        break;
 
          && requeued_events_pending_p ())
        break;
 
-      /* If wait_for_cell. check for keyboard input
-        but don't run any timers.
-        The reason for this is so that X events will be processed.
+      /* If we are not checking for keyboard input now,
+        do process events (but don't run any timers).
+        This is so that X events will be processed.
         Otherwise they may have to wait until polling takes place.
         Otherwise they may have to wait until polling takes place.
-        That would causes delays in pasting selections, for example.  */
-      if (wait_for_cell
-         && detect_input_pending ())
+        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 ())
        {
          swallow_events (do_display);
 #if 0  /* Exiting when read_kbd doesn't request that seems wrong, though.  */
        {
          swallow_events (do_display);
 #if 0  /* Exiting when read_kbd doesn't request that seems wrong, though.  */
@@ -2620,12 +2698,6 @@ read_process_output_error_handler (error)
   Fsleep_for (make_number (2), Qnil);
 }
 
   Fsleep_for (make_number (2), Qnil);
 }
 
-#ifdef WINDOWSNT
-#define READ_CHILD_OUTPUT read_child_output
-#else
-#define READ_CHILD_OUTPUT read
-#endif
-
 /* Read pending output from the process channel,
    starting with our buffered-ahead character if we have one.
    Yield number of decoded characters read.
 /* Read pending output from the process channel,
    starting with our buffered-ahead character if we have one.
    Yield number of decoded characters read.
@@ -2641,7 +2713,7 @@ read_process_output (proc, channel)
      Lisp_Object proc;
      register int channel;
 {
      Lisp_Object proc;
      register int channel;
 {
-  register int nchars;
+  register int nchars, nbytes;
   char *chars;
 #ifdef VMS
   int chars_allocated = 0;     /* If 1, `chars' should be freed later.  */
   char *chars;
 #ifdef VMS
   int chars_allocated = 0;     /* If 1, `chars' should be freed later.  */
@@ -2655,6 +2727,7 @@ read_process_output (proc, channel)
   struct coding_system *coding = proc_decode_coding_system[channel];
   int chars_in_decoding_buf = 0; /* If 1, `chars' points
                                    XSTRING (p->decoding_buf)->data.  */
   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
   VMS_PROC_STUFF *vs, *get_vms_process_pointer();
 
 #ifdef VMS
   VMS_PROC_STUFF *vs, *get_vms_process_pointer();
@@ -2670,89 +2743,104 @@ read_process_output (proc, channel)
   else
     error ("Could not get VMS process pointer");
   chars = vs->inputBuffer;
   else
     error ("Could not get VMS process pointer");
   chars = vs->inputBuffer;
-  nchars = clean_vms_buffer (chars, vs->iosb[1]);
-  if (nchars <= 0)
+  nbytes = clean_vms_buffer (chars, vs->iosb[1]);
+  if (nbytes <= 0)
     {
       start_vms_process_read (vs); /* Crank up the next read on the process */
       return 1;                        /* Nothing worth printing, say we got 1 */
     }
     {
       start_vms_process_read (vs); /* Crank up the next read on the process */
       return 1;                        /* Nothing worth printing, say we got 1 */
     }
-  if (coding->carryover_size)
+  if (carryover > 0)
     {
     {
-      /* The data carried over in the previous decoding should be
-         prepended to the new data read to decode all together.  */
-      char *buf = (char *) xmalloc (nchars + coding->carryover_size);
-
-      bcopy (coding->carryover, buf, coding->carryover_size);
-      bcopy (chars, buf + coding->carryover_size, nchars);
+      /* 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
+            + XSTRING (p->decoding_buf)->size_byte - carryover,
+            buf, carryover);
+      bcopy (chars, buf + carryover, nbytes);
       chars = buf;
       chars_allocated = 1;
     }
 #else /* not VMS */
 
       chars = buf;
       chars_allocated = 1;
     }
 #else /* not VMS */
 
-  if (coding->carryover_size)
-    /* The data carried over in the previous decoding should be
-       prepended to the new data read to decode all together.  */
-    bcopy (coding->carryover, buf, coding->carryover_size);
+  if (carryover)
+    /* See the comment above.  */
+    bcopy (XSTRING (p->decoding_buf)->data
+          + XSTRING (p->decoding_buf)->size_byte - carryover,
+          buf, carryover);
 
   if (proc_buffered_char[channel] < 0)
 
   if (proc_buffered_char[channel] < 0)
-    nchars = READ_CHILD_OUTPUT (channel, buf + coding->carryover_size,
-                               (sizeof buf) - coding->carryover_size);
+    nbytes = read (channel, buf + carryover, (sizeof buf) - carryover);
   else
     {
   else
     {
-      buf[coding->carryover_size] = proc_buffered_char[channel];
+      buf[carryover] = proc_buffered_char[channel];
       proc_buffered_char[channel] = -1;
       proc_buffered_char[channel] = -1;
-      nchars = READ_CHILD_OUTPUT (channel, buf + coding->carryover_size + 1,
-                                   (sizeof buf) - coding->carryover_size - 1);
-      if (nchars < 0)
-       nchars = 1;
+      nbytes = read (channel, buf + carryover + 1,
+                    (sizeof buf) - carryover - 1);
+      if (nbytes < 0)
+       nbytes = 1;
       else
       else
-       nchars = nchars + 1;
+       nbytes = nbytes + 1;
     }
   chars = buf;
 #endif /* not VMS */
 
     }
   chars = buf;
 #endif /* not VMS */
 
-  /* At this point, NCHARS holds number of characters just received
+  /* At this point, NBYTES holds number of characters just received
      (including the one in proc_buffered_char[channel]).  */
      (including the one in proc_buffered_char[channel]).  */
-  if (nchars <= 0) return nchars;
+  if (nbytes <= 0) return nbytes;
 
 
-  /* Now set NCHARS how many bytes we must decode.  */
-  nchars += coding->carryover_size;
+  /* Now set NBYTES how many bytes we must decode.  */
+  nbytes += carryover;
+  nchars = nbytes;
 
 
-  if (CODING_REQUIRE_CONVERSION (coding))
+  if (CODING_MAY_REQUIRE_DECODING (coding))
     {
     {
-      int require = decoding_buffer_size (coding, nchars);
-      int consumed, produced;
+      int require = decoding_buffer_size (coding, nbytes);
+      int result;
       
       
-      if (XSTRING (p->decoding_buf)->size < require)
+      if (XSTRING (p->decoding_buf)->size_byte < require)
        p->decoding_buf = make_uninit_string (require);
        p->decoding_buf = make_uninit_string (require);
-      produced = decode_coding (coding, chars, XSTRING (p->decoding_buf)->data,
-                               nchars, XSTRING (p->decoding_buf)->size,
-                               &consumed);
+      result = decode_coding (coding, chars, XSTRING (p->decoding_buf)->data,
+                             nbytes, XSTRING (p->decoding_buf)->size_byte);
+      carryover = nbytes - coding->consumed;
 
 
-      /* New coding-system might be found by `decode_coding'.  */
+      /* A new coding system might be found by `decode_coding'.  */
       if (!EQ (p->decode_coding_system, coding->symbol))
        {
          p->decode_coding_system = coding->symbol;
       if (!EQ (p->decode_coding_system, coding->symbol))
        {
          p->decode_coding_system = coding->symbol;
-         setup_coding_system (coding->symbol,
-                              proc_decode_coding_system[channel]);
-         /* If coding-system for encoding is not yet decided, we set it
-            as the same as coding-system for decoding.  */
-         if (NILP (p->encode_coding_system))
+
+         /* 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[p->outfd])
            {
              p->encode_coding_system = coding->symbol;
              setup_coding_system (coding->symbol,
            {
              p->encode_coding_system = coding->symbol;
              setup_coding_system (coding->symbol,
-                                  proc_encode_coding_system[channel]);
+                                  proc_encode_coding_system[p->outfd]);
            }
        }
            }
        }
+
 #ifdef VMS
       /*  Now we don't need the contents of `chars'.  */
       if (chars_allocated)
        free (chars);
 #endif
 #ifdef VMS
       /*  Now we don't need the contents of `chars'.  */
       if (chars_allocated)
        free (chars);
 #endif
-      if (produced == 0)
+      if (coding->produced == 0)
        return 0;
        return 0;
-      chars = XSTRING (p->decoding_buf)->data;
-      nchars = produced;
+      chars = (char *) XSTRING (p->decoding_buf)->data;
+      nbytes = coding->produced;
+      nchars = coding->produced_char;
       chars_in_decoding_buf = 1;
     }
 #ifdef VMS
       chars_in_decoding_buf = 1;
     }
 #ifdef VMS
@@ -2761,15 +2849,20 @@ read_process_output (proc, channel)
       /* 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)
       /* 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)
-         || XSTRING (p->decoding_buf)->size < nchars)
-       p->decoding_buf = make_uninit_string (nchars);
-      bcopy (chars, XSTRING (p->decoding_buf)->data, nchars);
+         || XSTRING (p->decoding_buf)->size < 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;
       free (chars);
       chars = XSTRING (p->decoding_buf)->data;
       chars_in_decoding_buf = 1;
+      carryover = 0;
     }
 #endif
 
     }
 #endif
 
+  XSETINT (p->decoding_carryover, carryover);
+  Vlast_coding_system_used = coding->symbol;
+
+  /* Read and dispose of the process output.  */
   outstream = p->filter;
   if (!NILP (outstream))
     {
   outstream = p->filter;
   if (!NILP (outstream))
     {
@@ -2779,6 +2872,7 @@ read_process_output (proc, channel)
       int count = specpdl_ptr - specpdl;
       Lisp_Object odeactivate;
       Lisp_Object obuffer, okeymap;
       int count = specpdl_ptr - specpdl;
       Lisp_Object odeactivate;
       Lisp_Object obuffer, okeymap;
+      Lisp_Object text;
       int outer_running_asynch_code = running_asynch_code;
 
       /* No need to gcpro these, because all we do with them later
       int outer_running_asynch_code = running_asynch_code;
 
       /* No need to gcpro these, because all we do with them later
@@ -2807,13 +2901,10 @@ read_process_output (proc, channel)
         save the match data in a special nonrecursive fashion.  */
       running_asynch_code = 1;
 
         save the match data in a special nonrecursive fashion.  */
       running_asynch_code = 1;
 
-      /* Read and dispose of the process output.  */
+      text = make_multibyte_string (chars, nchars, nbytes);
       internal_condition_case_1 (read_process_output_call,
                                 Fcons (outstream,
       internal_condition_case_1 (read_process_output_call,
                                 Fcons (outstream,
-                                       Fcons (proc,
-                                              Fcons (make_string (chars,
-                                                                  nchars),
-                                                     Qnil))),
+                                       Fcons (proc, Fcons (text, Qnil))),
                                 !NILP (Vdebug_on_error) ? Qnil : Qerror,
                                 read_process_output_error_handler);
 
                                 !NILP (Vdebug_on_error) ? Qnil : Qerror,
                                 read_process_output_error_handler);
 
@@ -2848,16 +2939,21 @@ read_process_output (proc, channel)
     {
       Lisp_Object old_read_only;
       int old_begv, old_zv;
     {
       Lisp_Object old_read_only;
       int old_begv, old_zv;
+      int old_begv_byte, old_zv_byte;
       Lisp_Object odeactivate;
       Lisp_Object odeactivate;
-      int before;
+      int before, before_byte;
+      int opoint_byte;
 
       odeactivate = Vdeactivate_mark;
 
       Fset_buffer (p->buffer);
       opoint = PT;
 
       odeactivate = Vdeactivate_mark;
 
       Fset_buffer (p->buffer);
       opoint = PT;
+      opoint_byte = PT_BYTE;
       old_read_only = current_buffer->read_only;
       old_begv = BEGV;
       old_zv = ZV;
       old_read_only = current_buffer->read_only;
       old_begv = BEGV;
       old_zv = ZV;
+      old_begv_byte = BEGV_BYTE;
+      old_zv_byte = ZV_BYTE;
 
       current_buffer->read_only = Qnil;
 
 
       current_buffer->read_only = Qnil;
 
@@ -2865,10 +2961,13 @@ read_process_output (proc, channel)
         at the current end-of-output marker,
         thus preserving logical ordering of input and output.  */
       if (XMARKER (p->mark)->buffer)
         at the current end-of-output marker,
         thus preserving logical ordering of input and output.  */
       if (XMARKER (p->mark)->buffer)
-       SET_PT (clip_to_bounds (BEGV, marker_position (p->mark), ZV));
+       SET_PT_BOTH (clip_to_bounds (BEGV, marker_position (p->mark), ZV),
+                    clip_to_bounds (BEGV_BYTE, marker_byte_position (p->mark),
+                                    ZV_BYTE));
       else
       else
-       SET_PT (ZV);
+       SET_PT_BOTH (ZV, ZV_BYTE);
       before = PT;
       before = PT;
+      before_byte = PT_BYTE;
 
       /* If the output marker is outside of the visible region, save
         the restriction and widen.  */
 
       /* If the output marker is outside of the visible region, save
         the restriction and widen.  */
@@ -2878,21 +2977,31 @@ read_process_output (proc, channel)
       /* 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)
       /* 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)
-       insert_from_string_before_markers (p->decoding_buf, 0, nchars, 0);
+       insert_from_string_before_markers (p->decoding_buf, 0, 0,
+                                          nchars, nbytes, 0);
       else
       else
-       insert_before_markers (chars, nchars);
-      Fset_marker (p->mark, make_number (PT), p->buffer);
+       insert_1_both (chars, nchars, nbytes, 0, 1, 1);
+      set_marker_both (p->mark, p->buffer, PT, PT_BYTE);
 
       update_mode_lines++;
 
       /* Make sure opoint and the old restrictions
         float ahead of any new text just as point would.  */
       if (opoint >= before)
 
       update_mode_lines++;
 
       /* Make sure opoint and the old restrictions
         float ahead of any new text just as point would.  */
       if (opoint >= before)
-       opoint += PT - before;
+       {
+         opoint += PT - before;
+         opoint_byte += PT_BYTE - before_byte;
+       }
       if (old_begv > before)
       if (old_begv > before)
-       old_begv += PT - before;
+       {
+         old_begv += PT - before;
+         old_begv_byte += PT_BYTE - before_byte;
+       }
       if (old_zv >= before)
       if (old_zv >= before)
-       old_zv += PT - before;
+       {
+         old_zv += PT - before;
+         old_zv_byte += PT_BYTE - before_byte;
+       }
 
       /* If the restriction isn't what it should be, set it.  */
       if (old_begv != BEGV || old_zv != ZV)
 
       /* If the restriction isn't what it should be, set it.  */
       if (old_begv != BEGV || old_zv != ZV)
@@ -2902,13 +3011,13 @@ read_process_output (proc, channel)
       Vdeactivate_mark = odeactivate;
 
       current_buffer->read_only = old_read_only;
       Vdeactivate_mark = odeactivate;
 
       current_buffer->read_only = old_read_only;
-      SET_PT (opoint);
+      SET_PT_BOTH (opoint, opoint_byte);
       set_buffer_internal (old);
     }
 #ifdef VMS
   start_vms_process_read (vs);
 #endif
       set_buffer_internal (old);
     }
 #ifdef VMS
   start_vms_process_read (vs);
 #endif
-  return nchars;
+  return nbytes;
 }
 
 DEFUN ("waiting-for-user-input-p", Fwaiting_for_user_input_p, Swaiting_for_user_input_p,
 }
 
 DEFUN ("waiting-for-user-input-p", Fwaiting_for_user_input_p, Swaiting_for_user_input_p,
@@ -2946,7 +3055,7 @@ send_process_trap ()
 
 send_process (proc, buf, len, object)
      volatile Lisp_Object proc;
 
 send_process (proc, buf, len, object)
      volatile Lisp_Object proc;
-     char *buf;
+     unsigned char *buf;
      int len;
      Lisp_Object object;
 {
      int len;
      Lisp_Object object;
 {
@@ -2955,6 +3064,7 @@ send_process (proc, buf, len, object)
   volatile unsigned char *procname = XSTRING (XPROCESS (proc)->name)->data;
   struct coding_system *coding;
   struct gcpro gcpro1;
   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);
 
 
   GCPRO1 (object);
 
@@ -2971,54 +3081,61 @@ send_process (proc, buf, len, object)
     error ("Output file descriptor of %s is closed", procname);
 
   coding = proc_encode_coding_system[XINT (XPROCESS (proc)->outfd)];
     error ("Output file descriptor of %s is closed", procname);
 
   coding = proc_encode_coding_system[XINT (XPROCESS (proc)->outfd)];
-  if (CODING_REQUIRE_CONVERSION (coding))
+  Vlast_coding_system_used = coding->symbol;
+
+  if (CODING_REQUIRE_ENCODING (coding))
     {
       int require = encoding_buffer_size (coding, len);
       int offset, dummy;
     {
       int require = encoding_buffer_size (coding, len);
       int offset, dummy;
-      char *temp_buf = NULL;
+      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 relocation.  */
       offset = (BUFFERP (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.  */
       offset = (BUFFERP (object)
-               ? BUF_PTR_CHAR_POS (XBUFFER (object), (unsigned char *) buf)
+               ? BUF_PTR_BYTE_POS (XBUFFER (object), buf)
                : (STRINGP (object)
                : (STRINGP (object)
-                  ? offset = buf - (char *) XSTRING (object)->data
+                  ? offset = buf - XSTRING (object)->data
                   : -1));
 
                   : -1));
 
-      if (coding->carryover_size > 0)
+      if (carryover > 0)
        {
        {
-         temp_buf = (char *) xmalloc (len + coding->carryover_size);
+         temp_buf = (unsigned char *) xmalloc (len + carryover);
 
          if (offset >= 0)
            {
              if (BUFFERP (object))
 
          if (offset >= 0)
            {
              if (BUFFERP (object))
-               buf = (char *) BUF_CHAR_ADDRESS (XBUFFER (object), offset);
+               buf = BUF_BYTE_ADDRESS (XBUFFER (object), offset);
              else if (STRINGP (object))
              else if (STRINGP (object))
-               buf = offset + (char *) XSTRING (object)->data;
+               buf = offset + XSTRING (object)->data;
              /* Now we don't have to care relocation.  */
              offset = -1;
            }
              /* Now we don't have to care relocation.  */
              offset = -1;
            }
-         bcopy (coding->carryover, temp_buf, coding->carryover_size);
-         bcopy (buf, temp_buf + coding->carryover_size, len);
+         bcopy ((XSTRING (XPROCESS (proc)->encoding_buf)->data
+                 + XSTRING (XPROCESS (proc)->encoding_buf)->size_byte
+                 - carryover),
+                temp_buf,
+                carryover);
+         bcopy (buf, temp_buf + carryover, len);
          buf = temp_buf;
        }
 
          buf = temp_buf;
        }
 
-      if (XSTRING (XPROCESS (proc)->encoding_buf)->size < require)
+      if (XSTRING (XPROCESS (proc)->encoding_buf)->size_byte < require)
        {
          XPROCESS (proc)->encoding_buf = make_uninit_string (require);
 
          if (offset >= 0)
            {
              if (BUFFERP (object))
        {
          XPROCESS (proc)->encoding_buf = make_uninit_string (require);
 
          if (offset >= 0)
            {
              if (BUFFERP (object))
-               buf = (char *) BUF_CHAR_ADDRESS (XBUFFER (object), offset);
+               buf = BUF_BYTE_ADDRESS (XBUFFER (object), offset);
              else if (STRINGP (object))
              else if (STRINGP (object))
-               buf = offset + (char *) XSTRING (object)->data;
+               buf = offset + XSTRING (object)->data;
            }
        }
       object = XPROCESS (proc)->encoding_buf;
            }
        }
       object = XPROCESS (proc)->encoding_buf;
-      len = encode_coding (coding, buf, XSTRING (object)->data,
-                          len, XSTRING (object)->size, &dummy);
+      encode_coding (coding, buf, XSTRING (object)->data,
+                    len, XSTRING (object)->size_byte);
+      len = coding->produced;
       buf = XSTRING (object)->data;
       if (temp_buf)
        xfree (temp_buf);
       buf = XSTRING (object)->data;
       if (temp_buf)
        xfree (temp_buf);
@@ -3064,8 +3181,8 @@ send_process (proc, buf, len, object)
               If that proves worth handling, we need to save linepos
               in the process object.  */
            int linepos = 0;
               If that proves worth handling, we need to save linepos
               in the process object.  */
            int linepos = 0;
-           char *ptr = buf;
-           char *end = buf + len;
+           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)
 
            /* Scan through this text for a line that is too long.  */
            while (ptr != end && linepos < pty_max_bytes)
@@ -3108,10 +3225,9 @@ send_process (proc, buf, len, object)
                    /* Running filters might relocate buffers or strings.
                       Arrange to relocate BUF.  */
                    if (BUFFERP (object))
                    /* Running filters might relocate buffers or strings.
                       Arrange to relocate BUF.  */
                    if (BUFFERP (object))
-                     offset = BUF_PTR_CHAR_POS (XBUFFER (object),
-                                                (unsigned char *) buf);
+                     offset = BUF_PTR_BYTE_POS (XBUFFER (object), buf);
                    else if (STRINGP (object))
                    else if (STRINGP (object))
-                     offset = buf - (char *) XSTRING (object)->data;
+                     offset = buf - XSTRING (object)->data;
 
                    XSETFASTINT (zero, 0);
 #ifdef EMACS_HAS_USECS
 
                    XSETFASTINT (zero, 0);
 #ifdef EMACS_HAS_USECS
@@ -3121,9 +3237,9 @@ send_process (proc, buf, len, object)
 #endif
 
                    if (BUFFERP (object))
 #endif
 
                    if (BUFFERP (object))
-                     buf = (char *) BUF_CHAR_ADDRESS (XBUFFER (object), offset);
+                     buf = BUF_BYTE_ADDRESS (XBUFFER (object), offset);
                    else if (STRINGP (object))
                    else if (STRINGP (object))
-                     buf = offset + (char *) XSTRING (object)->data;
+                     buf = offset + XSTRING (object)->data;
 
                    rv = 0;
                  }
 
                    rv = 0;
                  }
@@ -3172,16 +3288,17 @@ Output from processes can arrive in between bunches.")
      Lisp_Object process, start, end;
 {
   Lisp_Object proc;
      Lisp_Object process, start, end;
 {
   Lisp_Object proc;
-  int start1;
+  int start1, end1;
 
   proc = get_process (process);
   validate_region (&start, &end);
 
   if (XINT (start) < GPT && XINT (end) > GPT)
 
   proc = get_process (process);
   validate_region (&start, &end);
 
   if (XINT (start) < GPT && XINT (end) > GPT)
-    move_gap (start);
+    move_gap (XINT (start));
 
 
-  start1 = XINT (start);
-  send_process (proc, POS_ADDR (start1), XINT (end) - XINT (start),
+  start1 = CHAR_TO_BYTE (XINT (start));
+  end1 = CHAR_TO_BYTE (XINT (end));
+  send_process (proc, BYTE_POS_ADDR (start1), end1 - start1,
                Fcurrent_buffer ());
 
   return Qnil;
                Fcurrent_buffer ());
 
   return Qnil;
@@ -3201,7 +3318,8 @@ Output from processes can arrive in between bunches.")
   Lisp_Object proc;
   CHECK_STRING (string, 1);
   proc = get_process (process);
   Lisp_Object proc;
   CHECK_STRING (string, 1);
   proc = get_process (process);
-  send_process (proc, XSTRING (string)->data, XSTRING (string)->size, string);
+  send_process (proc, XSTRING (string)->data,
+               XSTRING (string)->size_byte, string);
   return Qnil;
 }
 \f
   return Qnil;
 }
 \f
@@ -3661,6 +3779,7 @@ text to PROCESS after you call this function.")
 /* Kill all processes associated with `buffer'.
  If `buffer' is nil, kill all processes  */
 
 /* Kill all processes associated with `buffer'.
  If `buffer' is nil, kill all processes  */
 
+void
 kill_buffer_processes (buffer)
      Lisp_Object buffer;
 {
 kill_buffer_processes (buffer)
      Lisp_Object buffer;
 {
@@ -3946,6 +4065,7 @@ exec_sentinel (proc, reason)
    (either run the sentinel or output a message).
    This is done while Emacs is waiting for keyboard input.  */
 
    (either run the sentinel or output a message).
    This is done while Emacs is waiting for keyboard input.  */
 
+void
 status_notify ()
 {
   register Lisp_Object proc, buffer;
 status_notify ()
 {
   register Lisp_Object proc, buffer;
@@ -4016,8 +4136,8 @@ status_notify ()
            {
              Lisp_Object ro, tem;
              struct buffer *old = current_buffer;
            {
              Lisp_Object ro, tem;
              struct buffer *old = current_buffer;
-             int opoint;
-             int before;
+             int opoint, opoint_byte;
+             int before, before_byte;
 
              ro = XBUFFER (buffer)->read_only;
 
 
              ro = XBUFFER (buffer)->read_only;
 
@@ -4028,15 +4148,17 @@ status_notify ()
              Fset_buffer (buffer);
 
              opoint = PT;
              Fset_buffer (buffer);
 
              opoint = PT;
+             opoint_byte = PT_BYTE;
              /* Insert new output into buffer
                 at the current end-of-output marker,
                 thus preserving logical ordering of input and output.  */
              if (XMARKER (p->mark)->buffer)
              /* Insert new output into buffer
                 at the current end-of-output marker,
                 thus preserving logical ordering of input and output.  */
              if (XMARKER (p->mark)->buffer)
-               SET_PT (marker_position (p->mark));
+               Fgoto_char (p->mark);
              else
              else
-               SET_PT (ZV);
+               SET_PT_BOTH (ZV, ZV_BYTE);
 
              before = PT;
 
              before = PT;
+             before_byte = PT_BYTE;
 
              tem = current_buffer->read_only;
              current_buffer->read_only = Qnil;
 
              tem = current_buffer->read_only;
              current_buffer->read_only = Qnil;
@@ -4045,12 +4167,13 @@ status_notify ()
              insert_string (" ");
              Finsert (1, &msg);
              current_buffer->read_only = tem;
              insert_string (" ");
              Finsert (1, &msg);
              current_buffer->read_only = tem;
-             Fset_marker (p->mark, make_number (PT), p->buffer);
+             set_marker_both (p->mark, p->buffer, PT, PT_BYTE);
 
              if (opoint >= before)
 
              if (opoint >= before)
-               SET_PT (opoint + (PT - before));
+               SET_PT_BOTH (opoint + (PT - before),
+                            opoint_byte + (PT_BYTE - before_byte));
              else
              else
-               SET_PT (opoint);
+               SET_PT_BOTH (opoint, opoint_byte);
 
              set_buffer_internal (old);
            }
 
              set_buffer_internal (old);
            }
@@ -4066,7 +4189,7 @@ status_notify ()
 \f
 DEFUN ("set-process-coding-system", Fset_process_coding_system,
        Sset_process_coding_system, 1, 3, 0,
 \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\
+  "Set coding systems of PROCESS to DECODING (input from the process) and\n\
 ENCODING (output to the process).")
   (proc, decoding, encoding)
      register Lisp_Object proc, decoding, encoding;
 ENCODING (output to the process).")
   (proc, decoding, encoding)
      register Lisp_Object proc, decoding, encoding;
@@ -4092,7 +4215,7 @@ ENCODING (output to the process).")
 
 DEFUN ("process-coding-system",
        Fprocess_coding_system, Sprocess_coding_system, 1, 1, 0,
 
 DEFUN ("process-coding-system",
        Fprocess_coding_system, Sprocess_coding_system, 1, 1, 0,
-  "Return a cons of coding-system for decoding and encoding of PROCESS.")
+  "Return a cons of coding systems for decoding and encoding of PROCESS.")
   (proc)
      register Lisp_Object proc;
 {
   (proc)
      register Lisp_Object proc;
 {