]> code.delx.au - gnu-emacs/blobdiff - src/process.c
Merged from miles@gnu.org--gnu-2005 (patch 438-440)
[gnu-emacs] / src / process.c
index db6e85c0fb3d8f55eb10ffacc8b77bc3fa75a94b..46808674a0dcd857db4ac8f4998618bb417bbc91 100644 (file)
@@ -1,6 +1,6 @@
 /* Asynchronous subprocess control for GNU Emacs.
-   Copyright (C) 1985, 86, 87, 88, 93, 94, 95, 96, 98, 1999,
-      2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1996, 1998, 1999,
+      2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -187,6 +187,7 @@ extern Lisp_Object QCfilter;
 #include "syswait.h"
 
 extern void set_waiting_for_input P_ ((EMACS_TIME *));
+extern char *get_operating_system_release ();
 
 #ifndef USE_CRT_DLL
 extern int errno;
@@ -271,17 +272,19 @@ int update_tick;
 #define READ_OUTPUT_DELAY_MAX       (READ_OUTPUT_DELAY_INCREMENT * 5)
 #define READ_OUTPUT_DELAY_MAX_MAX   (READ_OUTPUT_DELAY_INCREMENT * 7)
 
-/* Number of processes which might be delayed.  */
+/* Number of processes which have a non-zero read_output_delay,
+   and therefore might be delayed for adaptive read buffering.  */
 
 static int process_output_delay_count;
 
-/* Non-zero if any process has non-nil process_output_skip.  */
+/* Non-zero if any process has non-nil read_output_skip.  */
 
 static int process_output_skip;
 
 /* Non-nil means to delay reading process output to improve buffering.
    A value of t means that delay is reset after each send, any other
-   non-nil value does not reset the delay.  */
+   non-nil value does not reset the delay.  A value of nil disables
+   adaptive read buffering completely.  */
 static Lisp_Object Vprocess_adaptive_read_buffering;
 #else
 #define process_output_delay_count 0
@@ -375,8 +378,6 @@ 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, Vdefault_file_name_coding_system;
-
 #ifdef HAVE_PTYS
 #ifdef HAVE_PTY_H
 #include <pty.h>
@@ -1290,7 +1291,7 @@ list_processes_1 (query_only)
   XSETFASTINT (minspace, 1);
 
   set_buffer_internal (XBUFFER (Vstandard_output));
-  Fbuffer_disable_undo (Vstandard_output);
+  current_buffer->undo_list = Qt;
 
   current_buffer->truncate_lines = Qt;
 
@@ -1536,7 +1537,6 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS)  */)
 
   XPROCESS (proc)->childp = Qt;
   XPROCESS (proc)->plist = Qnil;
-  XPROCESS (proc)->command_channel_p = Qnil;
   XPROCESS (proc)->buffer = buffer;
   XPROCESS (proc)->sentinel = Qnil;
   XPROCESS (proc)->filter = Qnil;
@@ -2552,7 +2552,7 @@ DEFUN ("make-network-process", Fmake_network_process, Smake_network_process,
 In Emacs, network connections are represented by process objects, so
 input and output work as for subprocesses and `delete-process' closes
 a network connection.  However, a network process has no process id,
-it cannot be signalled, and the status codes are different from normal
+it cannot be signaled, and the status codes are different from normal
 processes.
 
 Arguments are specified as keyword/argument pairs.  The following
@@ -2722,7 +2722,6 @@ usage: (make-network-process &rest ARGS)  */)
   int xerrno = 0;
   int s = -1, outch, inch;
   struct gcpro gcpro1;
-  int retry = 0;
   int count = SPECPDL_INDEX ();
   int count1;
   Lisp_Object QCaddress;  /* one of QClocal or QCremote */
@@ -3023,6 +3022,8 @@ usage: (make-network-process &rest ARGS)  */)
     {
       int optn, optbits;
 
+    retry_connect:
+
       s = socket (lres->ai_family, lres->ai_socktype, lres->ai_protocol);
       if (s < 0)
        {
@@ -3101,8 +3102,6 @@ usage: (make-network-process &rest ARGS)  */)
          break;
        }
 
-    retry_connect:
-
       immediate_quit = 1;
       QUIT;
 
@@ -3144,22 +3143,13 @@ usage: (make-network-process &rest ARGS)  */)
 
       immediate_quit = 0;
 
-      if (xerrno == EINTR)
-       goto retry_connect;
-      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 retry_connect;
-       }
-
       /* Discard the unwind protect closing S.  */
       specpdl_ptr = specpdl + count1;
       emacs_close (s);
       s = -1;
+
+      if (xerrno == EINTR)
+       goto retry_connect;
     }
 
   if (s >= 0)
@@ -4330,6 +4320,11 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
 #endif
 
 #ifdef ADAPTIVE_READ_BUFFERING
+         /* Set the timeout for adaptive read buffering if any
+            process has non-nil read_output_skip and non-zero
+            read_output_delay, and we are not reading output for a
+            specific wait_channel.  It is not executed if
+            Vprocess_adaptive_read_buffering is nil.  */
          if (process_output_skip && check_delay > 0)
            {
              int usecs = EMACS_USECS (timeout);
@@ -4340,6 +4335,8 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
                  proc = chan_process[channel];
                  if (NILP (proc))
                    continue;
+                 /* Find minimum non-zero read_output_delay among the
+                    processes with non-nil read_output_skip.  */
                  if (XINT (XPROCESS (proc)->read_output_delay) > 0)
                    {
                      check_delay--;
@@ -4890,10 +4887,10 @@ read_process_output (proc, channel)
        {
          Lisp_Object tem;
          /* Don't clobber the CURRENT match data, either!  */
-         tem = Fmatch_data (Qnil, Qnil);
-         restore_match_data ();
-         record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
-         Fset_match_data (tem);
+         tem = Fmatch_data (Qnil, Qnil, Qnil);
+         restore_search_regs ();
+         record_unwind_save_match_data ();
+         Fset_match_data (tem, Qt);
        }
 
       /* For speed, if a search happens within this code,
@@ -4947,7 +4944,7 @@ read_process_output (proc, channel)
                                   read_process_output_error_handler);
 
       /* If we saved the match data nonrecursively, restore it now.  */
-      restore_match_data ();
+      restore_search_regs ();
       running_asynch_code = outer_running_asynch_code;
 
       /* Handling the process output should not deactivate the mark.  */
@@ -5114,10 +5111,12 @@ Lisp_Object process_sent_to;
 SIGTYPE
 send_process_trap ()
 {
+  SIGNAL_THREAD_CHECK (SIGPIPE);
 #ifdef BSD4_1
   sigrelse (SIGPIPE);
   sigrelse (SIGALRM);
 #endif /* BSD4_1 */
+  sigunblock (sigmask (SIGPIPE));
   longjmp (send_process_frame, 1);
 }
 
@@ -5143,6 +5142,7 @@ send_process (proc, buf, len, object)
   int rv;
   struct coding_system *coding;
   struct gcpro gcpro1;
+  SIGTYPE (*volatile old_sigpipe) ();
 
   GCPRO1 (object);
 
@@ -5267,7 +5267,6 @@ send_process (proc, buf, len, object)
       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.  */
@@ -5309,7 +5308,11 @@ send_process (proc, buf, len, object)
                               0, datagram_address[outfd].sa,
                               datagram_address[outfd].len);
                  if (rv < 0 && errno == EMSGSIZE)
-                   report_file_error ("sending datagram", Fcons (proc, Qnil));
+                   {
+                     signal (SIGPIPE, old_sigpipe);
+                     report_file_error ("sending datagram",
+                                        Fcons (proc, Qnil));
+                   }
                }
              else
 #endif
@@ -5406,6 +5409,7 @@ send_process (proc, buf, len, object)
 #endif /* not VMS */
   else
     {
+      signal (SIGPIPE, old_sigpipe);
 #ifndef VMS
       proc = process_sent_to;
       p = XPROCESS (proc);
@@ -6156,6 +6160,8 @@ sigchld_handler (signo)
   register struct Lisp_Process *p;
   extern EMACS_TIME *input_available_clear_time;
 
+  SIGNAL_THREAD_CHECK (signo);
+
 #ifdef BSD4_1
   extern int sigheld;
   sigheld |= sigbit (SIGCHLD);
@@ -6342,10 +6348,10 @@ exec_sentinel (proc, reason)
   if (outer_running_asynch_code)
     {
       Lisp_Object tem;
-      tem = Fmatch_data (Qnil, Qnil);
-      restore_match_data ();
-      record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
-      Fset_match_data (tem);
+      tem = Fmatch_data (Qnil, Qnil, Qnil);
+      restore_search_regs ();
+      record_unwind_save_match_data ();
+      Fset_match_data (tem, Qt);
     }
 
   /* For speed, if a search happens within this code,
@@ -6359,7 +6365,7 @@ exec_sentinel (proc, reason)
                             exec_sentinel_error_handler);
 
   /* If we saved the match data nonrecursively, restore it now.  */
-  restore_match_data ();
+  restore_search_regs ();
   running_asynch_code = outer_running_asynch_code;
 
   Vdeactivate_mark = odeactivate;
@@ -6708,6 +6714,19 @@ init_process ()
    Fprovide (intern ("make-network-process"), subfeatures);
  }
 #endif /* HAVE_SOCKETS */
+
+#if defined (DARWIN) || defined (MAC_OSX)
+  /* PTYs are broken on Darwin < 6, but are sometimes useful for interactive
+     processes.  As such, we only change the default value.  */
+ if (initialized)
+  {
+    char *release = get_operating_system_release();
+    if (!release || !release[0] || (release[0] < MIN_PTY_KERNEL_VERSION
+                                   && release[1] == '.')) {
+      Vprocess_connection_type = Qnil;
+    }
+  }
+#endif
 }
 
 void
@@ -6802,7 +6821,7 @@ The value takes effect when `start-process' is called.  */);
               doc: /* If non-nil, improve receive buffering by delaying after short reads.
 On some systems, when Emacs reads the output from a subprocess, the output data
 is read in very small blocks, potentially resulting in very poor performance.
-This behaviour can be remedied to some extent by setting this variable to a
+This behavior can be remedied to some extent by setting this variable to a
 non-nil value, as it will automatically delay reading from such processes, to
 allowing them to produce more output before Emacs tries to read it.
 If the value is t, the delay is reset after each write to the process; any other