(MAKE_LOCK_NAME): Use size_byte.
[bpt/emacs.git] / src / process.c
index fe1cd20..d2779dd 100644 (file)
@@ -107,6 +107,8 @@ Boston, MA 02111-1307, USA.  */
 #include "frame.h"
 #include "blockinput.h"
 
+#define max(a, b) ((a) > (b) ? (a) : (b))
+
 Lisp_Object Qprocessp;
 Lisp_Object Qrun, Qstop, Qsignal, Qopen, Qclosed;
 Lisp_Object Qlast_nonmenu_event;
@@ -224,6 +226,10 @@ static SELECT_TYPE input_wait_mask;
 
 static SELECT_TYPE non_keyboard_wait_mask;
 
+/* Mask that excludes process input descriptor (s).  */
+
+static SELECT_TYPE non_process_wait_mask;
+
 /* The largest descriptor currently in use for a process object.  */
 static int max_process_desc;
 
@@ -260,6 +266,8 @@ extern int timers_run;
 /* 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.  */
 
@@ -1151,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))
-    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))
@@ -1163,25 +1172,37 @@ Remaining arguments are strings to give program as arguments.")
   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;
 
-      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 = Qemacs_mule;
+      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);
-         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;
+         else
+           val = Qnil;
        }
       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))
            {
@@ -1189,11 +1210,16 @@ 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);
-             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;
+         else
+           val = Qnil;
        }
       XPROCESS (proc)->encode_coding_system = val;
     }
@@ -1201,7 +1227,7 @@ Remaining arguments are strings to give program as arguments.")
   XPROCESS (proc)->decoding_buf = make_uninit_string (0);
   XPROCESS (proc)->encoding_buf = make_uninit_string (0);
 
-  create_process (proc, new_argv, current_dir);
+  create_process (proc, (char **) new_argv, current_dir);
 
   return unbind_to (count, proc);
 }
@@ -1256,6 +1282,7 @@ create_process_sigchld ()
 #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;
@@ -1374,6 +1401,35 @@ create_process (process, new_argv, current_dir)
   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->last_block = 1;
+      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);
+         int produced, dmy;
+
+         produced = encode_coding (coding, new_argv[i], buf, len, size, &dmy);
+         buf[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->last_block = 0;
+    }
+
   /* Delay interrupts until we have a chance to store
      the new fork's pid in its process structure */
 #ifdef POSIX_SIGNALS
@@ -1430,6 +1486,9 @@ create_process (process, new_argv, current_dir)
        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)
@@ -1851,9 +1910,7 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\
 #endif /* TERM */
 
   inch = s;
-  outch = dup (s);
-  if (outch < 0) 
-    report_file_error ("error duplicating socket", Fcons (name, Qnil));
+  outch = s;
 
   if (!NILP (buffer))
     buffer = Fget_buffer_create (buffer);
@@ -1894,32 +1951,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;
-      /* 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;
 
-      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
+           Qemacs_mule, 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);
-         coding_systems = Ffind_coding_system (5, args);
+         coding_systems = Ffind_operation_coding_system (5, args);
          UNGCPRO;
-         val = (CONSP (coding_systems) ? XCONS (coding_systems)->car : Qnil);
+         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;
 
-      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);
-             coding_systems = Ffind_coding_system (5, args);
+             coding_systems = Ffind_operation_coding_system (5, args);
              UNGCPRO;
            }
-         val = (CONSP (coding_systems) ? XCONS (coding_systems)->cdr : Qnil);
+         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;
     }
@@ -1943,6 +2022,7 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\
 }
 #endif /* HAVE_SOCKETS */
 
+void
 deactivate_process (proc)
      Lisp_Object proc;
 {
@@ -1992,6 +2072,7 @@ deactivate_process (proc)
    with subprocess.  This is used in a newly-forked subprocess
    to get rid of irrelevant descriptors.  */
 
+void
 close_process_descs ()
 {
 #ifndef WINDOWSNT
@@ -2236,6 +2317,11 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
              goto retry;
            }
 
+         /* If there is unread keyboard input, also return.  */
+         if (XINT (read_kbd) != 0
+             && requeued_events_pending_p ())
+           break;
+
          if (! EMACS_TIME_NEG_P (timer_delay) && time_limit != -1)
            {
              EMACS_TIME difference;
@@ -2271,7 +2357,8 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
        {
          Atemp = input_wait_mask;
          EMACS_SET_SECS_USECS (timeout, 0, 0);
-         if ((select (MAXDESC, &Atemp, (SELECT_TYPE *)0, (SELECT_TYPE *)0,
+         if ((select (max (max_process_desc, max_keyboard_desc) + 1,
+                      &Atemp, (SELECT_TYPE *)0, (SELECT_TYPE *)0,
                       &timeout)
               <= 0))
            {
@@ -2288,13 +2375,34 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
       if (wait_proc != 0
          && ! EQ (wait_proc->status, Qrun))
        {
+         int nread, total_nread = 0;
+
          clear_waiting_for_input ();
+         XSETPROCESS (proc, wait_proc);
+
+         /* Read data from the process, until we exhaust it.  */
+         while (XINT (wait_proc->infd) >= 0
+                && (nread
+                    = read_process_output (proc, XINT (wait_proc->infd))))
+           {
+              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 ();
+
          break;
        }
 
       /* Wait till there is something to do */
 
-      if (! XINT (read_kbd) && wait_for_cell == 0)
+      if (wait_for_cell)
+       Available = non_process_wait_mask;
+      else if (! XINT (read_kbd))
        Available = non_keyboard_wait_mask;
       else
        Available = input_wait_mask;
@@ -2318,7 +2426,8 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
          FD_ZERO (&Available);
        }
       else
-       nfds = select (MAXDESC, &Available, (SELECT_TYPE *)0, (SELECT_TYPE *)0,
+       nfds = select (max (max_process_desc, max_keyboard_desc) + 1,
+                      &Available, (SELECT_TYPE *)0, (SELECT_TYPE *)0,
                       &timeout);
 
       xerrno = errno;
@@ -2382,11 +2491,26 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
        kill (getpid (), SIGIO);
 #endif
 
+#if 0 /* When polling is used, interrupt_input is 0,
+        so get_input_pending should read the input.
+        So this should not be needed.  */
+      /* If we are using polling for input,
+        and we see input available, make it get read now.
+        Otherwise it might not actually get read for a second.
+        And on hpux, since we turn off polling in wait_reading_process_input,
+        it might never get read at all if we don't spend much time
+        outside of wait_reading_process_input.  */
+      if (XINT (read_kbd) && interrupt_input
+         && keyboard_bit_set (&Available)
+         && input_polling_used ())
+       kill (getpid (), SIGALRM);
+#endif
+
       /* Check for keyboard input */
       /* 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);
@@ -2394,18 +2518,25 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
            break;
        }
 
-      /* If wait_for_cell. check for keyboard input
-        but don't run any timers.
-        ??? (It seems wrong to me to check for keyboard
-        input at all when wait_for_cell, but the code
-        has been this way since July 1994.
-        Try changing this after version 19.31.)  */
-      if (wait_for_cell
-         && detect_input_pending ())
+      /* If there is unread keyboard input, also return.  */
+      if (XINT (read_kbd) != 0
+         && requeued_events_pending_p ())
+       break;
+
+      /* 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.
+        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.  */
          if (detect_input_pending ())
            break;
+#endif
        }
 
       /* Exit now if the cell we're waiting for became non-nil.  */
@@ -2413,13 +2544,13 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
        break;
 
 #ifdef SIGIO
-      /* If we think we have keyboard input waiting, but didn't get SIGIO
+      /* If we think we have keyboard input waiting, but didn't get SIGIO,
         go read it.  This can happen with X on BSD after logging out.
         In that case, there really is no input and no SIGIO,
         but select says there is input.  */
 
       if (XINT (read_kbd) && interrupt_input
-         && (keyboard_bit_set (&Available)))
+         && keyboard_bit_set (&Available))
        kill (getpid (), SIGIO);
 #endif
 
@@ -2539,7 +2670,7 @@ 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 periodic alarms back on */
-  start_polling();
+  start_polling ();
 #endif
    
   return got_some_input;
@@ -2564,12 +2695,6 @@ read_process_output_error_handler (error)
   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.
@@ -2639,14 +2764,14 @@ read_process_output (proc, channel)
     bcopy (coding->carryover, buf, coding->carryover_size);
 
   if (proc_buffered_char[channel] < 0)
-    nchars = READ_CHILD_OUTPUT (channel, buf + coding->carryover_size,
-                               (sizeof buf) - coding->carryover_size);
+    nchars = read (channel, buf + coding->carryover_size,
+                  (sizeof buf) - coding->carryover_size);
   else
     {
       buf[coding->carryover_size] = proc_buffered_char[channel];
       proc_buffered_char[channel] = -1;
-      nchars = READ_CHILD_OUTPUT (channel, buf + coding->carryover_size + 1,
-                                   (sizeof buf) - coding->carryover_size - 1);
+      nchars = read (channel, buf + coding->carryover_size + 1,
+                    (sizeof buf) - coding->carryover_size - 1);
       if (nchars < 0)
        nchars = 1;
       else
@@ -2662,7 +2787,8 @@ read_process_output (proc, channel)
   /* Now set NCHARS how many bytes we must decode.  */
   nchars += coding->carryover_size;
 
-  if (CODING_REQUIRE_CONVERSION (coding))
+  if (CODING_REQUIRE_DECODING (coding)
+      || CODING_REQUIRE_DETECTION (coding))
     {
       int require = decoding_buffer_size (coding, nchars);
       int consumed, produced;
@@ -2677,15 +2803,24 @@ read_process_output (proc, channel)
       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 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,
-                                  proc_encode_coding_system[channel]);
+                                  proc_encode_coding_system[p->outfd]);
            }
        }
 #ifdef VMS
@@ -2695,7 +2830,7 @@ read_process_output (proc, channel)
 #endif
       if (produced == 0)
        return 0;
-      chars = XSTRING (p->decoding_buf)->data;
+      chars = (char *) XSTRING (p->decoding_buf)->data;
       nchars = produced;
       chars_in_decoding_buf = 1;
     }
@@ -2714,6 +2849,8 @@ read_process_output (proc, channel)
     }
 #endif
 
+  Vlast_coding_system_used = coding->symbol;
+
   outstream = p->filter;
   if (!NILP (outstream))
     {
@@ -2791,16 +2928,22 @@ read_process_output (proc, channel)
   if (!NILP (p->buffer) && !NILP (XBUFFER (p->buffer)->name))
     {
       Lisp_Object old_read_only;
-      Lisp_Object old_begv, old_zv;
+      int old_begv, old_zv;
+      int old_begv_byte, old_zv_byte;
       Lisp_Object odeactivate;
+      int before, before_byte;
+      int opoint_byte;
 
       odeactivate = Vdeactivate_mark;
 
       Fset_buffer (p->buffer);
       opoint = PT;
+      opoint_byte = PT_BYTE;
       old_read_only = current_buffer->read_only;
-      XSETFASTINT (old_begv, BEGV);
-      XSETFASTINT (old_zv, ZV);
+      old_begv = BEGV;
+      old_zv = ZV;
+      old_begv_byte = BEGV_BYTE;
+      old_zv_byte = ZV_BYTE;
 
       current_buffer->read_only = Qnil;
 
@@ -2808,45 +2951,56 @@ 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)
-       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
-       SET_PT (ZV);
+       SET_PT_BOTH (ZV, ZV_BYTE);
+      before = PT;
+      before_byte = PT_BYTE;
 
       /* If the output marker is outside of the visible region, save
         the restriction and widen.  */
       if (! (BEGV <= PT && PT <= ZV))
        Fwiden ();
 
-      /* Make sure opoint floats ahead of any new text, just as point
-        would.  */
-      if (PT <= opoint)
-       opoint += nchars;
-
-      /* Insert after old_begv, but before old_zv.  */
-      if (PT < XFASTINT (old_begv))
-       XSETFASTINT (old_begv, XFASTINT (old_begv) + nchars);
-      if (PT <= XFASTINT (old_zv))
-       XSETFASTINT (old_zv, XFASTINT (old_zv) + nchars);
-
       /* 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);
       else
        insert_before_markers (chars, nchars);
-      Fset_marker (p->mark, make_number (PT), p->buffer);
+      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)
+       {
+         opoint += PT - before;
+         opoint_byte += PT_BYTE - before_byte;
+       }
+      if (old_begv > before)
+       {
+         old_begv += PT - before;
+         old_begv_byte += PT_BYTE - before_byte;
+       }
+      if (old_zv >= before)
+       {
+         old_zv += PT - before;
+         old_zv_byte += PT_BYTE - before_byte;
+       }
+
       /* If the restriction isn't what it should be, set it.  */
-      if (XFASTINT (old_begv) != BEGV || XFASTINT (old_zv) != ZV)
-       Fnarrow_to_region (old_begv, old_zv);
+      if (old_begv != BEGV || old_zv != ZV)
+       Fnarrow_to_region (make_number (old_begv), make_number (old_zv));
 
       /* Handling the process output should not deactivate the mark.  */
       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
@@ -2890,7 +3044,7 @@ send_process_trap ()
 
 send_process (proc, buf, len, object)
      volatile Lisp_Object proc;
-     char *buf;
+     unsigned char *buf;
      int len;
      Lisp_Object object;
 {
@@ -2915,31 +3069,33 @@ send_process (proc, buf, len, object)
     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;
-      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)
-               ? BUF_PTR_CHAR_POS (XBUFFER (object), (unsigned char *) buf)
+               ? BUF_PTR_BYTE_POS (XBUFFER (object), buf)
                : (STRINGP (object)
-                  ? offset = buf - (char *) XSTRING (object)->data
+                  ? offset = buf - XSTRING (object)->data
                   : -1));
 
       if (coding->carryover_size > 0)
        {
-         temp_buf = (char *) xmalloc (len + coding->carryover_size);
+         temp_buf = (unsigned char *) xmalloc (len + coding->carryover_size);
 
          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))
-               buf = offset + (char *) XSTRING (object)->data;
+               buf = offset + XSTRING (object)->data;
              /* Now we don't have to care relocation.  */
              offset = -1;
            }
@@ -2955,9 +3111,9 @@ send_process (proc, buf, len, 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))
-               buf = offset + (char *) XSTRING (object)->data;
+               buf = offset + XSTRING (object)->data;
            }
        }
       object = XPROCESS (proc)->encoding_buf;
@@ -3008,8 +3164,8 @@ send_process (proc, buf, len, object)
               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)
@@ -3052,10 +3208,9 @@ send_process (proc, buf, len, 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))
-                     offset = buf - (char *) XSTRING (object)->data;
+                     offset = buf - XSTRING (object)->data;
 
                    XSETFASTINT (zero, 0);
 #ifdef EMACS_HAS_USECS
@@ -3065,9 +3220,9 @@ send_process (proc, buf, len, object)
 #endif
 
                    if (BUFFERP (object))
-                     buf = (char *) BUF_CHAR_ADDRESS (XBUFFER (object), offset);
+                     buf = BUF_BYTE_ADDRESS (XBUFFER (object), offset);
                    else if (STRINGP (object))
-                     buf = offset + (char *) XSTRING (object)->data;
+                     buf = offset + XSTRING (object)->data;
 
                    rv = 0;
                  }
@@ -3116,16 +3271,17 @@ Output from processes can arrive in between bunches.")
      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)
-    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;
@@ -3582,7 +3738,20 @@ text to PROCESS after you call this function.")
     send_process (proc, "\004", 1, Qnil);
   else
     {
+#ifdef HAVE_SHUTDOWN
+      /* If this is a network connection, or socketpair is used
+        for communication with the subprocess, call shutdown to cause EOF.
+        (In some old system, shutdown to socketpair doesn't work.
+        Then we just can't win.)  */
+      if (NILP (XPROCESS (proc)->pid)
+         || XINT (XPROCESS (proc)->outfd) == XINT (XPROCESS (proc)->infd))
+       shutdown (XINT (XPROCESS (proc)->outfd), 1);
+      /* In case of socketpair, outfd == infd, so don't close it.  */
+      if (XINT (XPROCESS (proc)->outfd) != XINT (XPROCESS (proc)->infd))
+       close (XINT (XPROCESS (proc)->outfd));
+#else /* not HAVE_SHUTDOWN */
       close (XINT (XPROCESS (proc)->outfd));
+#endif /* not HAVE_SHUTDOWN */
       XSETINT (XPROCESS (proc)->outfd, open (NULL_DEVICE, O_WRONLY));
     }
 #endif /* VMS */
@@ -3592,6 +3761,7 @@ text to PROCESS after you call this function.")
 /* Kill all processes associated with `buffer'.
  If `buffer' is nil, kill all processes  */
 
+void
 kill_buffer_processes (buffer)
      Lisp_Object buffer;
 {
@@ -3877,6 +4047,7 @@ exec_sentinel (proc, reason)
    (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;
@@ -3947,7 +4118,8 @@ status_notify ()
            {
              Lisp_Object ro, tem;
              struct buffer *old = current_buffer;
-             int opoint;
+             int opoint, opoint_byte;
+             int before, before_byte;
 
              ro = XBUFFER (buffer)->read_only;
 
@@ -3956,16 +4128,19 @@ status_notify ()
              if (NILP (XBUFFER (buffer)->name))
                continue;
              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)
-               SET_PT (marker_position (p->mark));
+               Fgoto_char (p->mark);
              else
-               SET_PT (ZV);
-             if (PT <= opoint)
-               opoint += XSTRING (msg)->size + XSTRING (p->name)->size + 10;
+               SET_PT_BOTH (ZV, ZV_BYTE);
+
+             before = PT;
+             before_byte = PT_BYTE;
 
              tem = current_buffer->read_only;
              current_buffer->read_only = Qnil;
@@ -3974,9 +4149,14 @@ status_notify ()
              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)
+               SET_PT_BOTH (opoint + (PT - before),
+                            opoint_byte + (PT_BYTE - before_byte));
+             else
+               SET_PT_BOTH (opoint, opoint_byte);
 
-             SET_PT (opoint);
              set_buffer_internal (old);
            }
        }
@@ -3991,7 +4171,7 @@ status_notify ()
 \f
 DEFUN ("set-process-coding-system", Fset_process_coding_system,
        Sset_process_coding_system, 1, 3, 0,
-  "Set coding-systems of PROCESS to DECODING (input from the process) and\n\
+  "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;
@@ -4017,7 +4197,7 @@ ENCODING (output to the process).")
 
 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;
 {
@@ -4041,6 +4221,7 @@ add_keyboard_wait_descriptor (desc)
     FD_CLR (0, &input_wait_mask);
   add_keyboard_wait_descriptor_called_flag = 1;
   FD_SET (desc, &input_wait_mask);
+  FD_SET (desc, &non_process_wait_mask);
   if (desc > max_keyboard_desc)
     max_keyboard_desc = desc;
 }
@@ -4055,6 +4236,7 @@ delete_keyboard_wait_descriptor (desc)
   int lim = max_keyboard_desc;
 
   FD_CLR (desc, &input_wait_mask);
+  FD_CLR (desc, &non_process_wait_mask);
 
   if (desc == max_keyboard_desc)
     for (fd = 0; fd < lim; fd++)
@@ -4093,6 +4275,7 @@ init_process ()
 
   FD_ZERO (&input_wait_mask);
   FD_ZERO (&non_keyboard_wait_mask);
+  FD_ZERO (&non_process_wait_mask);
   max_process_desc = 0;
 
   FD_SET (0, &input_wait_mask);