Promote SSDATA macro from gtkutil.c and xsmfns.c to lisp.h.
[bpt/emacs.git] / src / process.c
index 6ff8f47..5f28cc6 100644 (file)
@@ -1,7 +1,7 @@
 /* Asynchronous subprocess control for GNU Emacs.
    Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995,
                 1996, 1998, 1999, 2001, 2002, 2003, 2004,
-                2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+                2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -31,11 +31,8 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #ifdef HAVE_INTTYPES_H
 #include <inttypes.h>
 #endif
-#include <stdlib.h>
 
-#ifdef HAVE_UNISTD_H
 #include <unistd.h>
-#endif
 #include <fcntl.h>
 
 /* Only MS-DOS does not define `subprocesses'.  */
@@ -57,21 +54,15 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #endif
 #endif
 
-#if defined(HAVE_SYS_IOCTL_H)
 #include <sys/ioctl.h>
 #if defined(HAVE_NET_IF_H)
 #include <net/if.h>
 #endif /* HAVE_NET_IF_H */
-#endif /* HAVE_SYS_IOCTL_H */
 
 #ifdef NEED_BSDTTY
 #include <bsdtty.h>
 #endif
 
-#ifdef HAVE_SYS_WAIT
-#include <sys/wait.h>
-#endif
-
 #ifdef HAVE_RES_INIT
 #include <netinet/in.h>
 #include <arpa/nameser.h>
@@ -82,6 +73,10 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <util.h>
 #endif
 
+#ifdef HAVE_PTY_H
+#include <pty.h>
+#endif
+
 #endif /* subprocesses */
 
 #include "lisp.h"
@@ -115,7 +110,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #ifdef HAVE_NS
 #include "nsterm.h"
 #endif
-extern int timers_run;
 
 Lisp_Object Qeuid, Qegid, Qcomm, Qstate, Qppid, Qpgrp, Qsess, Qttname, Qtpgid;
 Lisp_Object Qminflt, Qmajflt, Qcminflt, Qcmajflt, Qutime, Qstime, Qcstime;
@@ -127,9 +121,6 @@ Lisp_Object QCname, QCtype;
 
 static int kbd_is_on_hold;
 
-/* Nonzero means delete a process right away if it exits.  */
-static int delete_exited_processes;
-
 /* Nonzero means don't run process sentinels.  This is used
    when exiting.  */
 int inhibit_sentinels;
@@ -171,13 +162,6 @@ extern Lisp_Object QCfilter;
 /* Define first descriptor number available for subprocesses.  */
 #define FIRST_PROC_DESC 3
 
-/* Define SIGCHLD as an alias for SIGCLD.  There are many conditionals
-   testing SIGCHLD.  */
-
-#if !defined (SIGCHLD) && defined (SIGCLD)
-#define SIGCHLD SIGCLD
-#endif /* SIGCLD */
-
 extern const char *get_operating_system_release (void);
 
 /* From sysdep.c or w32.c  */
@@ -188,10 +172,6 @@ extern void serial_configure (struct Lisp_Process *p, Lisp_Object contact);
 extern int h_errno;
 #endif
 
-/* t means use pty, nil means use a pipe,
-   maybe other values to come.  */
-static Lisp_Object Vprocess_connection_type;
-
 /* These next two vars are non-static since sysdep.c uses them in the
    emulation of `select'.  */
 /* Number of events of change of status of a process.  */
@@ -201,8 +181,10 @@ int update_tick;
 
 /* Define NON_BLOCKING_CONNECT if we can support non-blocking connects.  */
 
+/* Only W32 has this, it really means that select can't take write mask.  */
 #ifdef BROKEN_NON_BLOCKING_CONNECT
 #undef NON_BLOCKING_CONNECT
+#define SELECT_CANT_DO_WRITE_MASK
 #else
 #ifndef NON_BLOCKING_CONNECT
 #ifdef HAVE_SELECT
@@ -258,11 +240,6 @@ static int process_output_delay_count;
 
 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.  A value of nil disables
-   adaptive read buffering completely.  */
-static Lisp_Object Vprocess_adaptive_read_buffering;
 #else
 #define process_output_delay_count 0
 #endif
@@ -354,14 +331,6 @@ struct sockaddr_and_len {
 /* Maximum number of bytes to send to a pty without an eof.  */
 static int pty_max_bytes;
 
-#ifdef HAVE_PTYS
-#ifdef HAVE_PTY_H
-#include <pty.h>
-#endif
-/* The file name of the pty opened by allocate_pty.  */
-
-static char pty_name[24];
-#endif
 \f
 
 struct fd_callback_data
@@ -442,7 +411,7 @@ delete_write_fd (int fd)
               max_input_desc = fd;
               break;
             }
-      
+
     }
 }
 
@@ -529,7 +498,7 @@ status_message (struct Lisp_Process *p)
          if (! NILP (Vlocale_coding_system))
            string = (code_convert_string_norecord
                      (string, Vlocale_coding_system, 0));
-         c1 = STRING_CHAR ((char *) SDATA (string));
+         c1 = STRING_CHAR (SSDATA (string));
          c2 = DOWNCASE (c1);
          if (c1 != c2)
            Faset (string, make_number (0), make_number (c2));
@@ -561,6 +530,9 @@ status_message (struct Lisp_Process *p)
 \f
 #ifdef HAVE_PTYS
 
+/* The file name of the pty opened by allocate_pty.  */
+static char pty_name[24];
+
 /* Open an available pty, returning a file descriptor.
    Return -1 on failure.
    The file name of the terminal corresponding to the pty
@@ -669,6 +641,8 @@ make_process (Lisp_Object name)
 
 #ifdef HAVE_GNUTLS
   p->gnutls_initstage = GNUTLS_STAGE_EMPTY;
+  p->gnutls_log_level = 0;
+  p->gnutls_p = 0;
 #endif
 
   /* If name is already in use, modify it until it is unused.  */
@@ -1446,7 +1420,7 @@ list_processes_1 (Lisp_Object query_only)
            port = Fformat_network_address (Fplist_get (p->childp, QClocal), Qnil);
          sprintf (tembuf, "(network %s server on %s)\n",
                   (DATAGRAM_CHAN_P (p->infd) ? "datagram" : "stream"),
-                  (STRINGP (port) ? (char *)SDATA (port) : "?"));
+                  (STRINGP (port) ? SSDATA (port) : "?"));
          insert_string (tembuf);
        }
       else if (NETCONN1_P (p))
@@ -1464,7 +1438,7 @@ list_processes_1 (Lisp_Object query_only)
            host = Fformat_network_address (Fplist_get (p->childp, QCremote), Qnil);
          sprintf (tembuf, "(network %s connection to %s)\n",
                   (DATAGRAM_CHAN_P (p->infd) ? "datagram" : "stream"),
-                  (STRINGP (host) ? (char *)SDATA (host) : "?"));
+                  (STRINGP (host) ? SSDATA (host) : "?"));
          insert_string (tembuf);
        }
       else if (SERIALCONN1_P (p))
@@ -1678,6 +1652,11 @@ 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
+       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
+       the process.  */
   }
 
 
@@ -1720,6 +1699,7 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS)  */)
        tem = Fsubstring (tem, make_number (2), Qnil);
 
       {
+       Lisp_Object arg_encoding = Qnil;
        struct gcpro gcpro1;
        GCPRO1 (tem);
 
@@ -1737,9 +1717,14 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS)  */)
            tem = Fcons (args[i], tem);
            CHECK_STRING (XCAR (tem));
            if (STRING_MULTIBYTE (XCAR (tem)))
-             XSETCAR (tem,
-                      code_convert_string_norecord
-                      (XCAR (tem), XPROCESS (proc)->encode_coding_system, 1));
+             {
+               if (NILP (arg_encoding))
+                 arg_encoding = (complement_process_encoding_system
+                                 (XPROCESS (proc)->encode_coding_system));
+               XSETCAR (tem,
+                        code_convert_string_norecord
+                        (XCAR (tem), arg_encoding, 1));
+             }
          }
 
        UNGCPRO;
@@ -1875,12 +1860,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
     }
 #endif
 
-#if 0
-  /* Replaced by close_process_descs */
-  set_exclusive_use (inchannel);
-  set_exclusive_use (outchannel);
-#endif
-
 #ifdef O_NONBLOCK
   fcntl (inchannel, F_SETFL, O_NONBLOCK);
   fcntl (outchannel, F_SETFL, O_NONBLOCK);
@@ -2538,7 +2517,7 @@ set_socket_option (int s, Lisp_Object opt, Lisp_Object val)
 
   CHECK_SYMBOL (opt);
 
-  name = (char *) SDATA (SYMBOL_NAME (opt));
+  name = SSDATA (SYMBOL_NAME (opt));
   for (sopt = socket_options; sopt->name; sopt++)
     if (strcmp (name, sopt->name) == 0)
       break;
@@ -2577,7 +2556,7 @@ set_socket_option (int s, Lisp_Object opt, Lisp_Object val)
        memset (devname, 0, sizeof devname);
        if (STRINGP (val))
          {
-           char *arg = (char *) SDATA (val);
+           char *arg = SSDATA (val);
            int len = min (strlen (arg), IFNAMSIZ);
            memcpy (devname, arg, len);
          }
@@ -2862,7 +2841,7 @@ usage:  (make-serial-process &rest ARGS)  */)
   record_unwind_protect (make_serial_process_unwind, proc);
   p = XPROCESS (proc);
 
-  fd = serial_open ((char*) SDATA (port));
+  fd = serial_open (SSDATA (port));
   p->infd = fd;
   p->outfd = fd;
   if (fd > max_process_desc)
@@ -3398,7 +3377,7 @@ usage: (make-network-process &rest ARGS)  */)
        /* Attempt to interpret host as numeric inet address */
        {
          unsigned long numeric_addr;
-         numeric_addr = inet_addr ((char *) SDATA (host));
+         numeric_addr = inet_addr (SSDATA (host));
          if (numeric_addr == -1)
            error ("Unknown host \"%s\"", SDATA (host));
 
@@ -3814,7 +3793,7 @@ usage: (make-network-process &rest ARGS)  */)
 }
 
 \f
-#if defined(HAVE_NET_IF_H) && defined(HAVE_SYS_IOCTL_H)
+#if defined(HAVE_NET_IF_H)
 
 #ifdef SIOCGIFCONF
 DEFUN ("network-interface-list", Fnetwork_interface_list, Snetwork_interface_list, 0, 0, 0,
@@ -4057,7 +4036,7 @@ FLAGS is the current flags of the interface.  */)
   return any ? res : Qnil;
 }
 #endif
-#endif /* defined(HAVE_NET_IF_H) && defined(HAVE_SYS_IOCTL_H) */
+#endif /* defined(HAVE_NET_IF_H) */
 
 /* Turn off input and output for process PROC.  */
 
@@ -4726,7 +4705,11 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
          else
            Available = input_wait_mask;
           Writeok = write_mask;
+#ifdef SELECT_CANT_DO_WRITE_MASK
+          check_write = 0;
+#else
           check_write = 1;
+#endif
          check_delay = wait_channel >= 0 ? 0 : process_output_delay_count;
        }
 
@@ -5061,6 +5044,7 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
              struct Lisp_Process *p;
 
              FD_CLR (channel, &connect_wait_mask);
+              FD_CLR (channel, &write_mask);
              if (--num_pending_connects < 0)
                abort ();
 
@@ -5195,8 +5179,8 @@ read_process_output (Lisp_Object proc, register int channel)
   if (proc_buffered_char[channel] < 0)
     {
 #ifdef HAVE_GNUTLS
-      if (NETCONN_P(proc) && GNUTLS_PROCESS_USABLE (proc))
-       nbytes = emacs_gnutls_read (channel, XPROCESS (proc)->gnutls_state,
+      if (XPROCESS (proc)->gnutls_p)
+       nbytes = emacs_gnutls_read (channel, XPROCESS (proc),
                                     chars + carryover, readmax);
       else
 #endif
@@ -5234,8 +5218,8 @@ read_process_output (Lisp_Object proc, register int channel)
       chars[carryover] = proc_buffered_char[channel];
       proc_buffered_char[channel] = -1;
 #ifdef HAVE_GNUTLS
-      if (NETCONN_P(proc) && GNUTLS_PROCESS_USABLE (proc))
-       nbytes = emacs_gnutls_read (channel, XPROCESS (proc)->gnutls_state,
+      if (XPROCESS (proc)->gnutls_p)
+       nbytes = emacs_gnutls_read (channel, XPROCESS (proc),
                                     chars + carryover + 1, readmax - 1);
       else
 #endif
@@ -5538,12 +5522,21 @@ send_process (volatile Lisp_Object proc, const unsigned char *volatile buf,
          && !NILP (XBUFFER (object)->enable_multibyte_characters))
       || EQ (object, Qt))
     {
+      p->encode_coding_system
+       = complement_process_encoding_system (p->encode_coding_system);
       if (!EQ (Vlast_coding_system_used, p->encode_coding_system))
-       /* The coding system for encoding was changed to raw-text
-          because we sent a unibyte text previously.  Now we are
-          sending a multibyte text, thus we must encode it by the
-          original coding system specified for the current process.  */
-       setup_coding_system (p->encode_coding_system, coding);
+       {
+         /* The coding system for encoding was changed to raw-text
+            because we sent a unibyte text previously.  Now we are
+            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
+            complement_process_encoding_system.  */
+         setup_coding_system (p->encode_coding_system, coding);
+         Vlast_coding_system_used = p->encode_coding_system;
+       }
       coding->src_multibyte = 1;
     }
   else
@@ -5650,9 +5643,9 @@ send_process (volatile Lisp_Object proc, const unsigned char *volatile buf,
 #endif
                {
 #ifdef HAVE_GNUTLS
-                 if (NETCONN_P(proc) && GNUTLS_PROCESS_USABLE (proc))
+                 if (XPROCESS (proc)->gnutls_p)
                    rv = emacs_gnutls_write (outfd,
-                                            XPROCESS (proc)->gnutls_state, 
+                                            XPROCESS (proc),
                                             (char *) buf, this);
                  else
 #endif
@@ -7086,10 +7079,12 @@ wait_reading_process_output (int time_limit, int microsecs, int read_kbd,
 void
 add_keyboard_wait_descriptor (int desc)
 {
+#ifdef subprocesses /* actually means "not MSDOS" */
   FD_SET (desc, &input_wait_mask);
   FD_SET (desc, &non_process_wait_mask);
   if (desc > max_input_desc)
     max_input_desc = desc;
+#endif
 }
 
 /* From now on, do not expect DESC to give keyboard input.  */
@@ -7097,6 +7092,7 @@ add_keyboard_wait_descriptor (int desc)
 void
 delete_keyboard_wait_descriptor (int desc)
 {
+#ifdef subprocesses
   int fd;
   int lim = max_input_desc;
 
@@ -7107,6 +7103,7 @@ delete_keyboard_wait_descriptor (int desc)
     for (fd = 0; fd < lim; fd++)
       if (FD_ISSET (fd, &input_wait_mask) || FD_ISSET (fd, &write_mask))
         max_input_desc = fd;
+#endif
 }
 
 /* Setup coding systems of PROCESS.  */
@@ -7633,14 +7630,14 @@ syms_of_process (void)
   Qargs = intern_c_string ("args");
   staticpro (&Qargs);
 
-  DEFVAR_BOOL ("delete-exited-processes", &delete_exited_processes,
+  DEFVAR_BOOL ("delete-exited-processes", delete_exited_processes,
               doc: /* *Non-nil means delete processes immediately when they exit.
 A value of nil means don't delete them until `list-processes' is run.  */);
 
   delete_exited_processes = 1;
 
 #ifdef subprocesses
-  DEFVAR_LISP ("process-connection-type", &Vprocess_connection_type,
+  DEFVAR_LISP ("process-connection-type", Vprocess_connection_type,
               doc: /* Control type of device used to communicate with subprocesses.
 Values are nil to use a pipe, or t or `pty' to use a pty.
 The value has no effect if the system has no ptys or if all ptys are busy:
@@ -7649,7 +7646,7 @@ The value takes effect when `start-process' is called.  */);
   Vprocess_connection_type = Qt;
 
 #ifdef ADAPTIVE_READ_BUFFERING
-  DEFVAR_LISP ("process-adaptive-read-buffering", &Vprocess_adaptive_read_buffering,
+  DEFVAR_LISP ("process-adaptive-read-buffering", Vprocess_adaptive_read_buffering,
               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.
@@ -7693,14 +7690,14 @@ The variable takes effect when `start-process' is called.  */);
   defsubr (&Sset_network_process_option);
   defsubr (&Smake_network_process);
   defsubr (&Sformat_network_address);
-#if defined(HAVE_NET_IF_H) && defined(HAVE_SYS_IOCTL_H)
+#if defined(HAVE_NET_IF_H)
 #ifdef SIOCGIFCONF
   defsubr (&Snetwork_interface_list);
 #endif
 #if defined(SIOCGIFADDR) || defined(SIOCGIFHWADDR) || defined(SIOCGIFFLAGS)
   defsubr (&Snetwork_interface_info);
 #endif
-#endif /* defined(HAVE_NET_IF_H) && defined(HAVE_SYS_IOCTL_H) */
+#endif /* defined(HAVE_NET_IF_H) */
 #ifdef DATAGRAM_SOCKETS
   defsubr (&Sprocess_datagram_address);
   defsubr (&Sset_process_datagram_address);
@@ -7730,6 +7727,3 @@ The variable takes effect when `start-process' is called.  */);
   defsubr (&Slist_system_processes);
   defsubr (&Sprocess_attributes);
 }
-
-/* arch-tag: 3706c011-7b9a-4117-bd4f-59e7f701a4c4
-   (do not change this comment) */