* objects.texi (Process Type, Overlay Type): Tweak page-breaks.
[bpt/emacs.git] / src / process.c
index c316139..f6f1ad0 100644 (file)
@@ -1,6 +1,6 @@
 /* Asynchronous subprocess control for GNU Emacs.
 
-Copyright (C) 1985-1988, 1993-1996, 1998-1999, 2001-2011
+Copyright (C) 1985-1988, 1993-1996, 1998-1999, 2001-2012
   Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -640,7 +640,10 @@ make_process (Lisp_Object name)
 
 #ifdef HAVE_GNUTLS
   p->gnutls_initstage = GNUTLS_STAGE_EMPTY;
+  /* Default log level.  */
   p->gnutls_log_level = 0;
+  /* GnuTLS handshakes attempted for this connection.  */
+  p->gnutls_handshakes_tried = 0;
   p->gnutls_p = 0;
   p->gnutls_state = NULL;
   p->gnutls_x509_cred = NULL;
@@ -1067,7 +1070,9 @@ is more appropriate for saving the process buffer.
 
 Binding the variable `inherit-process-coding-system' to non-nil before
 starting the process is an alternative way of setting the inherit flag
-for the process which will run.  */)
+for the process which will run.
+
+This function returns FLAG.  */)
   (register Lisp_Object process, Lisp_Object flag)
 {
   CHECK_PROCESS (process);
@@ -1080,7 +1085,8 @@ DEFUN ("set-process-query-on-exit-flag",
        2, 2, 0,
        doc: /* Specify if query is needed for PROCESS when Emacs is exited.
 If the second argument FLAG is non-nil, Emacs will query the user before
-exiting or killing a buffer if PROCESS is running.  */)
+exiting or killing a buffer if PROCESS is running.  This function
+returns FLAG.  */)
   (register Lisp_Object process, Lisp_Object flag)
 {
   CHECK_PROCESS (process);
@@ -1414,7 +1420,7 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS)  */)
          val = XCDR (Vdefault_process_coding_system);
       }
     XPROCESS (proc)->encode_coding_system = val;
-    /* Note: At this momemnt, the above coding system may leave
+    /* Note: At this moment, the above coding system may leave
        text-conversion or eol-conversion unspecified.  They will be
        decided after we read output from the process and decode it by
        some coding system, or just before we actually send a text to
@@ -1521,8 +1527,9 @@ start_process_unwind (Lisp_Object proc)
   if (!PROCESSP (proc))
     abort ();
 
-  /* Was PROC started successfully?  */
-  if (XPROCESS (proc)->pid == -1)
+  /* Was PROC started successfully?
+     -2 is used for a pty with no process, eg for gdb.  */
+  if (XPROCESS (proc)->pid <= 0 && XPROCESS (proc)->pid != -2)
     remove_process (proc);
 
   return Qnil;
@@ -2521,7 +2528,7 @@ could be "COM1", or "\\\\.\\COM10" for ports higher than COM9 (double
 the backslashes in strings).
 
 :speed SPEED -- (mandatory) is handled by `serial-process-configure',
-which is called by `make-serial-process'.
+which this function calls.
 
 :name NAME -- NAME is the name of the process.  If NAME is not given,
 the value of PORT is used.
@@ -2550,13 +2557,12 @@ but you can send outgoing data.  The stopped state is cleared by
 
 :plist PLIST -- Install PLIST as the initial plist of the process.
 
-:speed
 :bytesize
 :parity
 :stopbits
 :flowcontrol
--- These arguments are handled by `serial-process-configure', which is
-called by `make-serial-process'.
+-- This function calls `serial-process-configure' to handle these
+arguments.
 
 The original argument list, possibly modified by later configuration,
 is available via the function `process-contact'.
@@ -2790,7 +2796,7 @@ The stopped state is cleared by `continue-process' and set by
 :filter-multibyte BOOL -- If BOOL is non-nil, strings given to the
 process filter are multibyte, otherwise they are unibyte.
 If this keyword is not specified, the strings are multibyte if
-`default-enable-multibyte-characters' is non-nil.
+the default value of `enable-multibyte-characters' is non-nil.
 
 :sentinel SENTINEL -- Install SENTINEL as the process sentinel.
 
@@ -3120,7 +3126,7 @@ usage: (make-network-process &rest ARGS)  */)
     {
       struct hostent *host_info_ptr;
 
-      /* gethostbyname may fail with TRY_AGAIN, but we don't honour that,
+      /* gethostbyname may fail with TRY_AGAIN, but we don't honor that,
         as it may `hang' Emacs for a very long time.  */
       immediate_quit = 1;
       QUIT;
@@ -3474,7 +3480,7 @@ usage: (make-network-process &rest ARGS)  */)
 
   {
     /* Setup coding systems for communicating with the network stream.  */
-    struct gcpro inner_gcpro1;
+    struct gcpro gcpro1;
     /* Qt denotes we have not yet called Ffind_operation_coding_system.  */
     Lisp_Object coding_systems = Qt;
     Lisp_Object fargs[5], val;
@@ -3491,7 +3497,7 @@ usage: (make-network-process &rest ARGS)  */)
             || (NILP (buffer) && NILP (BVAR (&buffer_defaults, 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
+        assume that they receive bare code including a sequence of
         CR LF.  */
       val = Qnil;
     else
@@ -3502,9 +3508,9 @@ usage: (make-network-process &rest ARGS)  */)
          {
            fargs[0] = Qopen_network_stream, fargs[1] = name,
              fargs[2] = buffer, fargs[3] = host, fargs[4] = service;
-           GCPRO1_VAR (proc, inner_gcpro);
+           GCPRO1 (proc);
            coding_systems = Ffind_operation_coding_system (5, fargs);
-           UNGCPRO_VAR (inner_gcpro);
+           UNGCPRO;
          }
        if (CONSP (coding_systems))
          val = XCAR (coding_systems);
@@ -3535,9 +3541,9 @@ usage: (make-network-process &rest ARGS)  */)
              {
                fargs[0] = Qopen_network_stream, fargs[1] = name,
                  fargs[2] = buffer, fargs[3] = host, fargs[4] = service;
-               GCPRO1_VAR (proc, inner_gcpro);
+               GCPRO1 (proc);
                coding_systems = Ffind_operation_coding_system (5, fargs);
-               UNGCPRO_VAR (inner_gcpro);
+               UNGCPRO;
              }
          }
        if (CONSP (coding_systems))
@@ -3717,7 +3723,7 @@ DEFUN ("network-interface-info", Fnetwork_interface_info, Snetwork_interface_inf
        doc: /* Return information about network interface named IFNAME.
 The return value is a list (ADDR BCAST NETMASK HWADDR FLAGS),
 where ADDR is the layer 3 address, BCAST is the layer 3 broadcast address,
-NETMASK is the layer 3 network mask, HWADDR is the layer 2 addres, and
+NETMASK is the layer 3 network mask, HWADDR is the layer 2 address, and
 FLAGS is the current flags of the interface.  */)
   (Lisp_Object ifname)
 {
@@ -4620,15 +4626,46 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
              some data in the TCP buffers so that select works, but
              with custom pull/push functions we need to check if some
              data is available in the buffers manually.  */
-          if (nfds == 0 &&
-              wait_proc && wait_proc->gnutls_p /* Check for valid process.  */
-              /* Do we have pending data?  */
-              && emacs_gnutls_record_check_pending (wait_proc->gnutls_state) > 0)
-          {
-              nfds = 1;
-              /* Set to Available.  */
-              FD_SET (wait_proc->infd, &Available);
-          }
+          if (nfds == 0)
+           {
+             if (! wait_proc)
+               {
+                 /* We're not waiting on a specific process, so loop
+                    through all the channels and check for data.
+                    This is a workaround needed for some versions of
+                    the gnutls library -- 2.12.14 has been confirmed
+                    to need it.  See
+                    http://comments.gmane.org/gmane.emacs.devel/145074 */
+                 for (channel = 0; channel < MAXDESC; ++channel)
+                   if (! NILP (chan_process[channel]))
+                     {
+                       struct Lisp_Process *p =
+                         XPROCESS (chan_process[channel]);
+                       if (p && p->gnutls_p && p->infd
+                           && ((emacs_gnutls_record_check_pending
+                                (p->gnutls_state))
+                               > 0))
+                         {
+                           nfds++;
+                           FD_SET (p->infd, &Available);
+                         }
+                     }
+               }
+             else
+               {
+                 /* Check this specific channel. */
+                 if (wait_proc->gnutls_p /* Check for valid process.  */
+                     /* Do we have pending data?  */
+                     && ((emacs_gnutls_record_check_pending
+                          (wait_proc->gnutls_state))
+                         > 0))
+                   {
+                     nfds = 1;
+                     /* Set to Available.  */
+                     FD_SET (wait_proc->infd, &Available);
+                   }
+               }
+           }
 #endif
        }
 
@@ -4856,15 +4893,27 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
                 It can't hurt.  */
              else if (nread == -1 && errno == EIO)
                {
-                 /* Clear the descriptor now, so we only raise the signal once.  */
+                 struct Lisp_Process *p = XPROCESS (proc);
+
+                 /* Clear the descriptor now, so we only raise the
+                    signal once.  */
                  FD_CLR (channel, &input_wait_mask);
                  FD_CLR (channel, &non_keyboard_wait_mask);
 
-                 kill (getpid (), SIGCHLD);
+                 if (p->pid == -2)
+                   {
+                     /* If the EIO occurs on a pty, sigchld_handler's
+                        wait3() will not find the process object to
+                        delete.  Do it here.  */
+                     p->tick = ++process_tick;
+                     p->status = Qfailed;
+                   }
+                  else
+                   kill (getpid (), SIGCHLD);
                }
 #endif /* HAVE_PTYS */
-             /* If we can detect process termination, don't consider the process
-                gone just because its pipe is closed.  */
+             /* If we can detect process termination, don't consider the
+                process gone just because its pipe is closed.  */
 #ifdef SIGCHLD
              else if (nread == 0 && !NETCONN_P (proc) && !SERIALCONN_P (proc))
                ;
@@ -5028,9 +5077,8 @@ read_process_output (Lisp_Object proc, register int channel)
          proc_buffered_char[channel] = -1;
        }
 #ifdef HAVE_GNUTLS
-      if (XPROCESS (proc)->gnutls_p)
-       nbytes = emacs_gnutls_read (XPROCESS (proc),
-                                   chars + carryover + buffered,
+      if (p->gnutls_p)
+       nbytes = emacs_gnutls_read (p, chars + carryover + buffered,
                                    readmax - buffered);
       else
 #endif
@@ -5377,8 +5425,8 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
             sending a multibyte text, thus we must encode it by the
             original coding system specified for the current process.
 
-            Another reason we comming here is that the coding system
-            was just complemented and new one was returned by
+            Another reason we come here is that the coding system
+            was just complemented and new one was returned by
             complement_process_encoding_system.  */
          setup_coding_system (p->encode_coding_system, coding);
          Vlast_coding_system_used = p->encode_coding_system;
@@ -5387,6 +5435,7 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
     }
   else
     {
+      coding->src_multibyte = 0;
       /* For sending a unibyte text, character code conversion should
         not take place but EOL conversion should.  So, setup raw-text
         or one of the subsidiary if we have not yet done it.  */
@@ -5494,9 +5543,8 @@ send_process (volatile Lisp_Object proc, const char *volatile buf,
 #endif
                {
 #ifdef HAVE_GNUTLS
-                 if (XPROCESS (proc)->gnutls_p)
-                   written = emacs_gnutls_write (XPROCESS (proc),
-                                                  buf, this);
+                 if (p->gnutls_p)
+                   written = emacs_gnutls_write (p, buf, this);
                  else
 #endif
                    written = emacs_write (outfd, buf, this);