]> code.delx.au - gnu-emacs/blobdiff - src/process.c
Fix Bug#22814
[gnu-emacs] / src / process.c
index 9d8fa2237f38b7ff32f9cc950cfc9d07655404f3..1eac5e12663b70967fc921d2702cae9b1c66e133 100644 (file)
@@ -1,6 +1,6 @@
 /* Asynchronous subprocess control for GNU Emacs.
 
-Copyright (C) 1985-1988, 1993-1996, 1998-1999, 2001-2015 Free Software
+Copyright (C) 1985-1988, 1993-1996, 1998-1999, 2001-2016 Free Software
 Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -103,13 +103,9 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "coding.h"
 #include "process.h"
 #include "frame.h"
-#include "termhooks.h"
 #include "termopts.h"
-#include "commands.h"
 #include "keyboard.h"
 #include "blockinput.h"
-#include "dispextern.h"
-#include "composite.h"
 #include "atimer.h"
 #include "sysselect.h"
 #include "syssignal.h"
@@ -957,7 +953,7 @@ DEFUN ("process-command", Fprocess_command, Sprocess_command, 1, 1, 0,
 This is a list of strings, the first string being the program executed
 and the rest of the strings being the arguments given to it.
 For a network or serial process, this is nil (process is running) or t
-\(process is stopped).  */)
+(process is stopped).  */)
   (register Lisp_Object process)
 {
   CHECK_PROCESS (process);
@@ -1402,7 +1398,6 @@ usage: (make-process &rest ARGS)  */)
   Lisp_Object buffer, name, command, program, proc, contact, current_dir, tem;
   Lisp_Object xstderr, stderrproc;
   ptrdiff_t count = SPECPDL_INDEX ();
-  struct gcpro gcpro1;
   USE_SAFE_ALLOCA;
 
   if (nargs == 0)
@@ -1410,7 +1405,6 @@ usage: (make-process &rest ARGS)  */)
 
   /* Save arguments for process-contact and clone-process.  */
   contact = Flist (nargs, args);
-  GCPRO1 (contact);
 
   buffer = Fplist_get (contact, QCbuffer);
   if (!NILP (buffer))
@@ -1419,18 +1413,8 @@ usage: (make-process &rest ARGS)  */)
   /* Make sure that the child will be able to chdir to the current
      buffer's current directory, or its unhandled equivalent.  We
      can't just have the child check for an error when it does the
-     chdir, since it's in a vfork.
-
-     We have to GCPRO around this because Fexpand_file_name and
-     Funhandled_file_name_directory might call a file name handling
-     function.  The argument list is protected by the caller, so all
-     we really have to worry about is buffer.  */
-  {
-    struct gcpro gcpro1;
-    GCPRO1 (buffer);
-    current_dir = encode_current_directory ();
-    UNGCPRO;
-  }
+     chdir, since it's in a vfork.  */
+  current_dir = encode_current_directory ();
 
   name = Fplist_get (contact, QCname);
   CHECK_STRING (name);
@@ -1454,15 +1438,12 @@ usage: (make-process &rest ARGS)  */)
     }
   else if (!NILP (xstderr))
     {
-      struct gcpro gcpro1, gcpro2;
       CHECK_STRING (program);
-      GCPRO2 (buffer, current_dir);
       stderrproc = CALLN (Fmake_pipe_process,
                          QCname,
                          concat2 (name, build_string (" stderr")),
                          QCbuffer,
                          Fget_buffer_create (xstderr));
-      UNGCPRO;
     }
 
   proc = make_process (name);
@@ -1526,7 +1507,6 @@ usage: (make-process &rest ARGS)  */)
     /* Qt denotes we have not yet called Ffind_operation_coding_system.  */
     Lisp_Object coding_systems = Qt;
     Lisp_Object val, *args2;
-    struct gcpro gcpro1, gcpro2;
 
     tem = Fplist_get (contact, QCcoding);
     if (!NILP (tem))
@@ -1548,10 +1528,8 @@ usage: (make-process &rest ARGS)  */)
        args2[i++] = buffer;
        for (tem2 = command; CONSP (tem2); tem2 = XCDR (tem2))
          args2[i++] = XCAR (tem2);
-       GCPRO2 (proc, current_dir);
        if (!NILP (program))
          coding_systems = Ffind_operation_coding_system (nargs2, args2);
-       UNGCPRO;
        if (CONSP (coding_systems))
          val = XCAR (coding_systems);
        else if (CONSP (Vdefault_process_coding_system))
@@ -1580,10 +1558,8 @@ usage: (make-process &rest ARGS)  */)
            args2[i++] = buffer;
            for (tem2 = command; CONSP (tem2); tem2 = XCDR (tem2))
              args2[i++] = XCAR (tem2);
-           GCPRO2 (proc, current_dir);
            if (!NILP (program))
              coding_systems = Ffind_operation_coding_system (nargs2, args2);
-           UNGCPRO;
          }
        if (CONSP (coding_systems))
          val = XCDR (coding_systems);
@@ -1616,13 +1592,9 @@ usage: (make-process &rest ARGS)  */)
          && !(SCHARS (program) > 1
               && IS_DEVICE_SEP (SREF (program, 1))))
        {
-         struct gcpro gcpro1, gcpro2;
-
          tem = Qnil;
-         GCPRO2 (buffer, current_dir);
          openp (Vexec_path, program, Vexec_suffixes, &tem,
                 make_number (X_OK), false);
-         UNGCPRO;
          if (NILP (tem))
            report_file_error ("Searching for program", program);
          tem = Fexpand_file_name (tem, Qnil);
@@ -1638,8 +1610,6 @@ usage: (make-process &rest ARGS)  */)
       tem = remove_slash_colon (tem);
 
       Lisp_Object arg_encoding = Qnil;
-      struct gcpro gcpro1;
-      GCPRO1 (tem);
 
       /* Encode the file name and put it in NEW_ARGV.
         That's where the child will use it to execute the program.  */
@@ -1666,8 +1636,6 @@ usage: (make-process &rest ARGS)  */)
          new_argc++;
        }
 
-      UNGCPRO;
-
       /* Now that everything is encoded we can collect the strings into
         NEW_ARGV.  */
       char **new_argv;
@@ -1685,7 +1653,6 @@ usage: (make-process &rest ARGS)  */)
   else
     create_pty (proc);
 
-  UNGCPRO;
   SAFE_FREE ();
   return unbind_to (count, proc);
 }
@@ -2110,7 +2077,6 @@ usage:  (make-pipe-process &rest ARGS)  */)
 {
   Lisp_Object proc, contact;
   struct Lisp_Process *p;
-  struct gcpro gcpro1;
   Lisp_Object name, buffer;
   Lisp_Object tem;
   ptrdiff_t specpdl_count;
@@ -2120,7 +2086,6 @@ usage:  (make-pipe-process &rest ARGS)  */)
     return Qnil;
 
   contact = Flist (nargs, args);
-  GCPRO1 (contact);
 
   name = Fplist_get (contact, QCname);
   CHECK_STRING (name);
@@ -2244,7 +2209,6 @@ usage:  (make-pipe-process &rest ARGS)  */)
 
   specpdl_ptr = specpdl + specpdl_count;
 
-  UNGCPRO;
   return proc;
 }
 
@@ -2408,7 +2372,7 @@ conv_lisp_to_sockaddr (int family, Lisp_Object address, struct sockaddr *sa, int
        {
          struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) sa;
          uint16_t *ip6 = (uint16_t *)&sin6->sin6_addr;
-         len = sizeof (sin6->sin6_addr) + 1;
+         len = sizeof (sin6->sin6_addr) / 2 + 1;
          hostport = XINT (p->contents[--len]);
          sin6->sin6_port = htons (hostport);
          for (i = 0; i < len; i++)
@@ -2706,7 +2670,7 @@ is not given or nil, 1 stopbit is used.
 :flowcontrol FLOWCONTROL -- FLOWCONTROL determines the type of
 flowcontrol to be used, which is either nil (don't use flowcontrol),
 the symbol `hw' (use RTS/CTS hardware flowcontrol), or the symbol `sw'
-\(use XON/XOFF software flowcontrol).  If FLOWCONTROL is not given, no
+(use XON/XOFF software flowcontrol).  If FLOWCONTROL is not given, no
 flowcontrol is used.
 
 `serial-process-configure' is called by `make-serial-process' for the
@@ -2714,12 +2678,12 @@ initial configuration of the serial port.
 
 Examples:
 
-\(serial-process-configure :process "/dev/ttyS0" :speed 1200)
+(serial-process-configure :process "/dev/ttyS0" :speed 1200)
 
-\(serial-process-configure
-    :buffer "COM1" :stopbits 1 :parity 'odd :flowcontrol 'hw)
+(serial-process-configure
+    :buffer "COM1" :stopbits 1 :parity \\='odd :flowcontrol \\='hw)
 
-\(serial-process-configure :port "\\\\.\\COM13" :bytesize 7)
+(serial-process-configure :port "\\\\.\\COM13" :bytesize 7)
 
 usage: (serial-process-configure &rest ARGS)  */)
   (ptrdiff_t nargs, Lisp_Object *args)
@@ -2727,10 +2691,8 @@ usage: (serial-process-configure &rest ARGS)  */)
   struct Lisp_Process *p;
   Lisp_Object contact = Qnil;
   Lisp_Object proc = Qnil;
-  struct gcpro gcpro1;
 
   contact = Flist (nargs, args);
-  GCPRO1 (contact);
 
   proc = Fplist_get (contact, QCprocess);
   if (NILP (proc))
@@ -2745,14 +2707,9 @@ usage: (serial-process-configure &rest ARGS)  */)
     error ("Not a serial process");
 
   if (NILP (Fplist_get (p->childp, QCspeed)))
-    {
-      UNGCPRO;
-      return Qnil;
-    }
+    return Qnil;
 
   serial_configure (p, contact);
-
-  UNGCPRO;
   return Qnil;
 }
 
@@ -2820,13 +2777,13 @@ is available via the function `process-contact'.
 
 Examples:
 
-\(make-serial-process :port "/dev/ttyS0" :speed 9600)
+(make-serial-process :port "/dev/ttyS0" :speed 9600)
 
-\(make-serial-process :port "COM1" :speed 115200 :stopbits 2)
+(make-serial-process :port "COM1" :speed 115200 :stopbits 2)
 
-\(make-serial-process :port "\\\\.\\COM13" :speed 1200 :bytesize 7 :parity 'odd)
+(make-serial-process :port "\\\\.\\COM13" :speed 1200 :bytesize 7 :parity \\='odd)
 
-\(make-serial-process :port "/dev/tty.BlueConsole-SPP-1" :speed nil)
+(make-serial-process :port "/dev/tty.BlueConsole-SPP-1" :speed nil)
 
 usage:  (make-serial-process &rest ARGS)  */)
   (ptrdiff_t nargs, Lisp_Object *args)
@@ -2834,7 +2791,6 @@ usage:  (make-serial-process &rest ARGS)  */)
   int fd = -1;
   Lisp_Object proc, contact, port;
   struct Lisp_Process *p;
-  struct gcpro gcpro1;
   Lisp_Object name, buffer;
   Lisp_Object tem, val;
   ptrdiff_t specpdl_count;
@@ -2843,7 +2799,6 @@ usage:  (make-serial-process &rest ARGS)  */)
     return Qnil;
 
   contact = Flist (nargs, args);
-  GCPRO1 (contact);
 
   port = Fplist_get (contact, QCport);
   if (NILP (port))
@@ -2946,7 +2901,6 @@ usage:  (make-serial-process &rest ARGS)  */)
 
   specpdl_ptr = specpdl + specpdl_count;
 
-  UNGCPRO;
   return proc;
 }
 
@@ -3137,7 +3091,6 @@ usage: (make-network-process &rest ARGS)  */)
   int ret = 0;
   int xerrno = 0;
   int s = -1, outch, inch;
-  struct gcpro gcpro1;
   ptrdiff_t count = SPECPDL_INDEX ();
   ptrdiff_t count1;
   Lisp_Object colon_address;  /* Either QClocal or QCremote.  */
@@ -3155,7 +3108,6 @@ usage: (make-network-process &rest ARGS)  */)
 
   /* Save arguments for process-contact and clone-process.  */
   contact = Flist (nargs, args);
-  GCPRO1 (contact);
 
 #ifdef WINDOWSNT
   /* Ensure socket support is loaded if available.  */
@@ -3722,7 +3674,6 @@ usage: (make-network-process &rest ARGS)  */)
 
   {
     /* Setup coding systems for communicating with the network stream.  */
-    struct gcpro gcpro1;
     /* Qt denotes we have not yet called Ffind_operation_coding_system.  */
     Lisp_Object coding_systems = Qt;
     Lisp_Object val;
@@ -3747,13 +3698,9 @@ usage: (make-network-process &rest ARGS)  */)
        if (NILP (host) || NILP (service))
          coding_systems = Qnil;
        else
-         {
-           GCPRO1 (proc);
-           coding_systems = CALLN (Ffind_operation_coding_system,
-                                   Qopen_network_stream, name, buffer,
-                                   host, service);
-           UNGCPRO;
-         }
+         coding_systems = CALLN (Ffind_operation_coding_system,
+                                 Qopen_network_stream, name, buffer,
+                                 host, service);
        if (CONSP (coding_systems))
          val = XCAR (coding_systems);
        else if (CONSP (Vdefault_process_coding_system))
@@ -3780,13 +3727,9 @@ usage: (make-network-process &rest ARGS)  */)
            if (NILP (host) || NILP (service))
              coding_systems = Qnil;
            else
-             {
-               GCPRO1 (proc);
-               coding_systems = CALLN (Ffind_operation_coding_system,
-                                       Qopen_network_stream, name, buffer,
-                                       host, service);
-               UNGCPRO;
-             }
+             coding_systems = CALLN (Ffind_operation_coding_system,
+                                     Qopen_network_stream, name, buffer,
+                                     host, service);
          }
        if (CONSP (coding_systems))
          val = XCDR (coding_systems);
@@ -3806,7 +3749,6 @@ usage: (make-network-process &rest ARGS)  */)
   p->inherit_coding_system_flag
     = !(!NILP (tem) || NILP (buffer) || !inherit_process_coding_system);
 
-  UNGCPRO;
   return proc;
 }
 
@@ -4913,6 +4855,10 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
              data is available in the buffers manually.  */
           if (nfds == 0)
            {
+             fd_set tls_available;
+             int set = 0;
+
+             FD_ZERO (&tls_available);
              if (! wait_proc)
                {
                  /* We're not waiting on a specific process, so loop
@@ -4933,7 +4879,8 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
                          {
                            nfds++;
                            eassert (p->infd == channel);
-                           FD_SET (p->infd, &Available);
+                           FD_SET (p->infd, &tls_available);
+                           set++;
                          }
                      }
                }
@@ -4950,9 +4897,12 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
                      nfds = 1;
                      eassert (0 <= wait_proc->infd);
                      /* Set to Available.  */
-                     FD_SET (wait_proc->infd, &Available);
+                     FD_SET (wait_proc->infd, &tls_available);
+                     set++;
                    }
                }
+             if (set)
+               Available = tls_available;
            }
 #endif
        }
@@ -5422,8 +5372,6 @@ read_and_dispose_of_process_output (struct Lisp_Process *p, char *chars,
   bool outer_running_asynch_code = running_asynch_code;
   int waiting = waiting_for_user_input_p;
 
-  /* No need to gcpro these, because all we do with them later
-     is test them for EQness, and none of them should be a string.  */
 #if 0
   Lisp_Object obuffer, okeymap;
   XSETBUFFER (obuffer, current_buffer);
@@ -6317,7 +6265,7 @@ SIGCODE may be an integer, or a symbol whose name is a signal name.  */)
        {
          Lisp_Object process_number
            = string_to_number (SSDATA (process), 10, 1);
-         if (INTEGERP (process_number) || FLOATP (process_number))
+         if (NUMBERP (process_number))
            tem = process_number;
        }
       process = tem;
@@ -6605,8 +6553,6 @@ exec_sentinel (Lisp_Object proc, Lisp_Object reason)
   if (inhibit_sentinels)
     return;
 
-  /* No need to gcpro these, because all we do with them later
-     is test them for EQness, and none of them should be a string.  */
   odeactivate = Vdeactivate_mark;
 #if 0
   Lisp_Object obuffer, okeymap;
@@ -6684,16 +6630,10 @@ status_notify (struct Lisp_Process *deleting_process,
 {
   Lisp_Object proc;
   Lisp_Object tail, msg;
-  struct gcpro gcpro1, gcpro2;
   int got_some_output = -1;
 
   tail = Qnil;
   msg = Qnil;
-  /* We need to gcpro tail; if read_process_output calls a filter
-     which deletes a process and removes the cons to which tail points
-     from Vprocess_alist, and then causes a GC, tail is an unprotected
-     reference.  */
-  GCPRO2 (tail, msg);
 
   /* Set this now, so that if new processes are created by sentinels
      that we run, we get called again to handle their status changes.  */
@@ -6750,11 +6690,12 @@ status_notify (struct Lisp_Process *deleting_process,
          p->update_tick = p->tick;
          /* Now output the message suitably.  */
          exec_sentinel (proc, msg);
+         if (BUFFERP (p->buffer))
+           /* In case it uses %s in mode-line-format.  */
+           bset_update_mode_line (XBUFFER (p->buffer));
        }
     } /* end for */
 
-  update_mode_lines = 24;  /* In case buffers use %s in mode-line-format.  */
-  UNGCPRO;
   return got_some_output;
 }
 
@@ -7235,8 +7176,10 @@ setup_process_coding_systems (Lisp_Object process)
 }
 
 DEFUN ("get-buffer-process", Fget_buffer_process, Sget_buffer_process, 1, 1, 0,
-       doc: /* Return the (or a) process associated with BUFFER.
-BUFFER may be a buffer or the name of one.  */)
+       doc: /* Return the (or a) live process associated with BUFFER.
+BUFFER may be a buffer or the name of one.
+Return nil if all processes associated with BUFFER have been
+deleted or killed.  */)
   (register Lisp_Object buffer)
 {
 #ifdef subprocesses
@@ -7351,7 +7294,7 @@ DEFUN ("process-attributes", Fprocess_attributes,
 
 Value is an alist where each element is a cons cell of the form
 
-    \(KEY . VALUE)
+    (KEY . VALUE)
 
 If this functionality is unsupported, the value is nil.