* dbusbind.c (xd_retrieve_arg): Pacify GCC on x86_64 GNU/Linux.
[bpt/emacs.git] / src / process.c
index e588b3b..c7ca36a 100644 (file)
@@ -1,13 +1,13 @@
 /* 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 Free Software Foundation, Inc.
+                 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 GNU Emacs is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
@@ -78,7 +78,7 @@ Boston, MA 02110-1301, USA.  */
 #include <client.h>
 #endif
 
-/* On some systems, e.g. DGUX, inet_addr returns a 'struct in_addr'. */
+/* On some systems, inet_addr returns a 'struct in_addr'. */
 #ifdef HAVE_BROKEN_INET_ADDR
 #define IN_ADDR struct in_addr
 #define NUMERIC_ADDR_ERROR (numeric_addr.s_addr == -1)
@@ -87,12 +87,12 @@ Boston, MA 02110-1301, USA.  */
 #define NUMERIC_ADDR_ERROR (numeric_addr == -1)
 #endif
 
-#if defined(BSD_SYSTEM) || defined(STRIDE)
+#if defined(BSD_SYSTEM)
 #include <sys/ioctl.h>
 #if !defined (O_NDELAY) && defined (HAVE_PTYS) && !defined(USG5)
 #include <fcntl.h>
 #endif /* HAVE_PTYS and no O_NDELAY */
-#endif /* BSD_SYSTEM || STRIDE */
+#endif /* BSD_SYSTEM */
 
 #ifdef BROKEN_O_NONBLOCK
 #undef O_NONBLOCK
@@ -121,6 +121,12 @@ Boston, MA 02110-1301, USA.  */
 #include <sys/wait.h>
 #endif
 
+#ifdef HAVE_RES_INIT
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+#endif
+
 #include "lisp.h"
 #include "systime.h"
 #include "systty.h"
@@ -130,11 +136,11 @@ Boston, MA 02110-1301, USA.  */
 #include "charset.h"
 #include "coding.h"
 #include "process.h"
+#include "frame.h"
 #include "termhooks.h"
 #include "termopts.h"
 #include "commands.h"
 #include "keyboard.h"
-#include "frame.h"
 #include "blockinput.h"
 #include "dispextern.h"
 #include "composite.h"
@@ -590,7 +596,6 @@ allocate_pty ()
 #else
             sprintf (pty_name, "/dev/tty%c%x", c, i);
 #endif /* no PTY_TTY_NAME_SPRINTF */
-#ifndef UNIPLUS
            if (access (pty_name, 6) != 0)
              {
                emacs_close (fd);
@@ -600,7 +605,6 @@ allocate_pty ()
                return -1;
 # endif /* IRIS */
              }
-#endif /* not UNIPLUS */
            setup_pty (fd);
            return fd;
          }
@@ -625,6 +629,7 @@ make_process (name)
   p->tick = 0;
   p->update_tick = 0;
   p->pid = 0;
+  p->pty_flag = 0;
   p->raw_status_new = 0;
   p->status = Qrun;
   p->mark = Fmake_marker ();
@@ -733,9 +738,9 @@ BUFFER may be a buffer or the name of one.  */)
   buf = Fget_buffer (buffer);
   if (NILP (buf)) return Qnil;
 
-  for (tail = Vprocess_alist; !NILP (tail); tail = Fcdr (tail))
+  for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail))
     {
-      proc = Fcdr (Fcar (tail));
+      proc = Fcdr (XCAR (tail));
       if (PROCESSP (proc) && EQ (XPROCESS (proc)->buffer, buf))
        return proc;
     }
@@ -1001,7 +1006,7 @@ DEFUN ("process-mark", Fprocess_mark, Sprocess_mark,
 DEFUN ("set-process-filter", Fset_process_filter, Sset_process_filter,
        2, 2, 0,
        doc: /* Give PROCESS the filter function FILTER; nil means no filter.
-t means stop accepting output from the process.
+A value of t means stop accepting output from the process.
 
 When a process has a filter, its buffer is not used for output.
 Instead, each time it does output, the entire string of output is
@@ -1339,11 +1344,11 @@ list_processes_1 (query_only)
   w_buffer = 6;  /* Buffer */
   w_tty = 0;     /* Omit if no ttys */
 
-  for (tail = Vprocess_alist; !NILP (tail); tail = Fcdr (tail))
+  for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail))
     {
       int i;
 
-      proc = Fcdr (Fcar (tail));
+      proc = Fcdr (XCAR (tail));
       p = XPROCESS (proc);
       if (NILP (p->childp))
        continue;
@@ -1354,8 +1359,11 @@ list_processes_1 (query_only)
        w_proc = i;
       if (!NILP (p->buffer))
        {
-         if (NILP (XBUFFER (p->buffer)->name) && w_buffer < 8)
-           w_buffer = 8;  /* (Killed) */
+         if (NILP (XBUFFER (p->buffer)->name))
+           {
+             if (w_buffer < 8)
+               w_buffer = 8;  /* (Killed) */
+           }
          else if ((i = SCHARS (XBUFFER (p->buffer)->name), (i > w_buffer)))
            w_buffer = i;
        }
@@ -1369,8 +1377,10 @@ list_processes_1 (query_only)
   if (w_tty)
     {
       XSETFASTINT (i_tty, XFASTINT (i_buffer) + w_buffer + 1);
-      XSETFASTINT (i_command, XFASTINT (i_buffer) + w_tty + 1);
-    } else {
+      XSETFASTINT (i_command, XFASTINT (i_tty) + w_tty + 1);
+    }
+  else
+    {
       i_tty = Qnil;
       XSETFASTINT (i_command, XFASTINT (i_buffer) + w_buffer + 1);
     }
@@ -1402,11 +1412,11 @@ list_processes_1 (query_only)
   Findent_to (i_command, minspace); write_string ("-------", -1);
   write_string ("\n", -1);
 
-  for (tail = Vprocess_alist; !NILP (tail); tail = Fcdr (tail))
+  for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail))
     {
       Lisp_Object symbol;
 
-      proc = Fcdr (Fcar (tail));
+      proc = Fcdr (XCAR (tail));
       p = XPROCESS (proc);
       if (NILP (p->childp))
        continue;
@@ -1880,12 +1890,12 @@ create_process (process, new_argv, current_dir)
 #endif
       if (forkin < 0)
        report_file_error ("Opening pty", Qnil);
-#if defined (RTU) || defined (UNIPLUS) || defined (DONT_REOPEN_PTY)
+#if defined (DONT_REOPEN_PTY)
       /* In the case that vfork is defined as fork, the parent process
         (Emacs) may send some data before the child process completes
         tty options setup.  So we setup tty before forking.  */
       child_setup_tty (forkout);
-#endif /* RTU or UNIPLUS or DONT_REOPEN_PTY */
+#endif /* DONT_REOPEN_PTY */
 #else
       forkin = forkout = -1;
 #endif /* not USG, or USG_SUBTTY_WORKS */
@@ -1926,15 +1936,6 @@ create_process (process, new_argv, current_dir)
   set_exclusive_use (outchannel);
 #endif
 
-/* Stride people say it's a mystery why this is needed
-   as well as the O_NDELAY, but that it fails without this.  */
-#if defined (STRIDE) || (defined (pfa) && defined (HAVE_PTYS))
-  {
-    int one = 1;
-    ioctl (inchannel, FIONBIO, &one);
-  }
-#endif
-
 #ifdef O_NONBLOCK
   fcntl (inchannel, F_SETFL, O_NONBLOCK);
   fcntl (outchannel, F_SETFL, O_NONBLOCK);
@@ -1984,7 +1985,7 @@ create_process (process, new_argv, current_dir)
 #ifdef BSD4_1
   sighold (SIGCHLD);
 #else /* not BSD4_1 */
-#if defined (BSD_SYSTEM) || defined (UNIPLUS) || defined (HPUX)
+#if defined (BSD_SYSTEM) || defined (HPUX)
   sigsetmask (sigmask (SIGCHLD));
 #else /* ordinary USG */
 #if 0
@@ -2098,7 +2099,7 @@ create_process (process, new_argv, current_dir)
          }
 #endif /* TIOCNOTTY */
 
-#if !defined (RTU) && !defined (UNIPLUS) && !defined (DONT_REOPEN_PTY)
+#if !defined (DONT_REOPEN_PTY)
 /*** There is a suggestion that this ought to be a
      conditional on TIOCSPGRP,
      or !(defined (HAVE_SETSID) && defined (TIOCSCTTY)).
@@ -2132,7 +2133,7 @@ create_process (process, new_argv, current_dir)
            ioctl (xforkout, TIOCSPGRP, &pgrp);
 #endif
          }
-#endif /* not UNIPLUS and not RTU and not DONT_REOPEN_PTY */
+#endif /* not DONT_REOPEN_PTY */
 
 #ifdef SETUP_SLAVE_PTY
        if (pty_flag)
@@ -2159,7 +2160,7 @@ create_process (process, new_argv, current_dir)
 #ifdef BSD4_1
        sigrelse (SIGCHLD);
 #else /* not BSD4_1 */
-#if defined (BSD_SYSTEM) || defined (UNIPLUS) || defined (HPUX)
+#if defined (BSD_SYSTEM) || defined (HPUX)
        sigsetmask (SIGEMPTYMASK);
 #else /* ordinary USG */
 #if 0
@@ -2170,10 +2171,10 @@ create_process (process, new_argv, current_dir)
 #endif /* SIGCHLD */
 #endif /* !POSIX_SIGNALS */
 
-#if !defined (RTU) && !defined (UNIPLUS) && !defined (DONT_REOPEN_PTY)
+#if !defined (DONT_REOPEN_PTY)
        if (pty_flag)
          child_setup_tty (xforkout);
-#endif /* not RTU and not UNIPLUS and not DONT_REOPEN_PTY */
+#endif /* not DONT_REOPEN_PTY */
 #ifdef WINDOWSNT
        pid = child_setup (xforkin, xforkout, xforkout,
                           new_argv, 1, current_dir);
@@ -2251,7 +2252,7 @@ create_process (process, new_argv, current_dir)
 #ifdef BSD4_1
   sigrelse (SIGCHLD);
 #else /* not BSD4_1 */
-#if defined (BSD_SYSTEM) || defined (UNIPLUS) || defined (HPUX)
+#if defined (BSD_SYSTEM) || defined (HPUX)
   sigsetmask (SIGEMPTYMASK);
 #else /* ordinary USG */
 #if 0
@@ -2677,6 +2678,7 @@ OPTION is not a supported option, return nil instead; otherwise return t.  */)
 \f
 /* A version of request_sigio suitable for a record_unwind_protect.  */
 
+#ifdef __ultrix__
 static Lisp_Object
 unwind_request_sigio (dummy)
      Lisp_Object dummy;
@@ -2685,6 +2687,7 @@ unwind_request_sigio (dummy)
     request_sigio ();
   return Qnil;
 }
+#endif
 
 /* Create a network stream/datagram client/server process.  Treated
    exactly like a normal process when reading and writing.  Primary
@@ -2721,7 +2724,9 @@ host, and only clients connecting to that address will be accepted.
 
 :service SERVICE -- SERVICE is name of the service desired, or an
 integer specifying a port number to connect to.  If SERVICE is t,
-a random port number is selected for the server.
+a random port number is selected for the server.  (If Emacs was
+compiled with getaddrinfo, a port number can also be specified as a
+string, e.g. "80", as well as an integer.  This is not portable.)
 
 :type TYPE -- TYPE is the type of connection.  The default (nil) is a
 stream type connection, `datagram' creates a datagram type connection.
@@ -2780,7 +2785,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 iff
+If this keyword is not specified, the strings are multibyte if
 `default-enable-multibyte-characters' is non-nil.
 
 :sentinel SENTINEL -- Install SENTINEL as the process sentinel.
@@ -3081,6 +3086,11 @@ usage: (make-network-process &rest ARGS)  */)
       hints.ai_family = family;
       hints.ai_socktype = socktype;
       hints.ai_protocol = 0;
+
+#ifdef HAVE_RES_INIT
+      res_init ();
+#endif
+
       ret = getaddrinfo (SDATA (host), portstring, &hints, &res);
       if (ret)
 #ifdef HAVE_GAI_STRERROR
@@ -3126,6 +3136,11 @@ usage: (make-network-process &rest ARGS)  */)
         as it may `hang' Emacs for a very long time.  */
       immediate_quit = 1;
       QUIT;
+
+#ifdef HAVE_RES_INIT
+      res_init ();
+#endif
+
       host_info_ptr = gethostbyname (SDATA (host));
       immediate_quit = 0;
 
@@ -3157,6 +3172,10 @@ usage: (make-network-process &rest ARGS)  */)
 
  open_socket:
 
+#ifdef __ultrix__
+  /* Previously this was compiled unconditionally, but that seems
+     unnecessary on modern systems, and `unrequest_sigio' was a noop
+     under X anyway. --lorentey */
   /* Kernel bugs (on Ultrix at least) cause lossage (not just EINTR)
      when connect is interrupted.  So let's not let it get interrupted.
      Note we do not turn off polling, because polling is only used
@@ -3173,6 +3192,7 @@ usage: (make-network-process &rest ARGS)  */)
       record_unwind_protect (unwind_request_sigio, Qnil);
       unrequest_sigio ();
     }
+#endif
 
   /* Do this in case we never enter the for-loop below.  */
   count1 = SPECPDL_INDEX ();
@@ -3917,7 +3937,7 @@ it specifies a fractional number of seconds to wait.
 If optional fourth arg JUST-THIS-ONE is non-nil, only accept output
 from PROCESS, suspending reading output from other processes.
 If JUST-THIS-ONE is an integer, don't run any timers either.
-Return non-nil iff we received any output before the timeout expired.  */)
+Return non-nil if we received any output before the timeout expired.  */)
      (process, seconds, millisec, just_this_one)
      register Lisp_Object process, seconds, millisec, just_this_one;
 {
@@ -4249,16 +4269,16 @@ select_wrapper (n, rfd, wfd, xfd, tmo)
      (and gobble terminal input into the buffer if any arrives).
 
    If WAIT_PROC is specified, wait until something arrives from that
-     process.  The return value is true iff we read some input from
+     process.  The return value is true if we read some input from
      that process.
 
    If JUST_WAIT_PROC is non-nil, handle only output from WAIT_PROC
      (suspending output from other processes).  A negative value
      means don't run any timers either.
 
-   If WAIT_PROC is specified, then the function returns true iff we
+   If WAIT_PROC is specified, then the function returns true if we
      received input from that process before the timeout elapsed.
-   Otherwise, return true iff we received input from any process.  */
+   Otherwise, return true if we received input from any process.  */
 
 int
 wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
@@ -4622,12 +4642,6 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
             not by DEC's bundled CC.  -JimB  */
          else if (xerrno == ENOMEM)
            no_avail = 1;
-#endif
-#ifdef ALLIANT
-         /* This happens for no known reason on ALLIANT.
-            I am guessing that this is the right response. -- RMS.  */
-         else if (xerrno == EFAULT)
-           no_avail = 1;
 #endif
          else if (xerrno == EBADF)
            {
@@ -4690,6 +4704,7 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
        {
          int old_timers_run = timers_run;
          struct buffer *old_buffer = current_buffer;
+         Lisp_Object old_window = selected_window;
          int leave = 0;
 
          if (detect_input_pending_run_timers (do_display))
@@ -4703,7 +4718,8 @@ wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,
             an alike.  Make read_key_sequence aware of that.  */
          if (timers_run != old_timers_run
              && waiting_for_user_input_p == -1
-             && old_buffer != current_buffer)
+             && (old_buffer != current_buffer
+             || !EQ (old_window, selected_window)))
            record_asynch_buffer_change ();
 
          if (leave)
@@ -6776,12 +6792,12 @@ status_notify (deleting_process)
      that we run, we get called again to handle their status changes.  */
   update_tick = process_tick;
 
-  for (tail = Vprocess_alist; !NILP (tail); tail = Fcdr (tail))
+  for (tail = Vprocess_alist; CONSP (tail); tail = XCDR (tail))
     {
       Lisp_Object symbol;
       register struct Lisp_Process *p;
 
-      proc = Fcdr (Fcar (tail));
+      proc = Fcdr (XCAR (tail));
       p = XPROCESS (proc);
 
       if (p->tick != p->update_tick)
@@ -6956,20 +6972,12 @@ DEFUN ("process-filter-multibyte-p", Fprocess_filter_multibyte_p,
 
 
 \f
-/* The first time this is called, assume keyboard input comes from DESC
-   instead of from where we used to expect it.
-   Subsequent calls mean assume input keyboard can come from DESC
-   in addition to other places.  */
-
-static int add_keyboard_wait_descriptor_called_flag;
+/* Add DESC to the set of keyboard input descriptors.  */
 
 void
 add_keyboard_wait_descriptor (desc)
      int desc;
 {
-  if (! add_keyboard_wait_descriptor_called_flag)
-    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)
@@ -7075,7 +7083,12 @@ init_process ()
   process_output_skip = 0;
 #endif
 
+  /* Don't do this, it caused infinite select loops.  The display
+     method should call add_keyboard_wait_descriptor on stdin if it
+     needs that.  */
+#if 0
   FD_SET (0, &input_wait_mask);
+#endif
 
   Vprocess_alist = Qnil;
 #ifdef SIGCHLD
@@ -7356,7 +7369,7 @@ Lisp_Object QCtype;
    do_display != 0 means redisplay should be done to show subprocess
    output that arrives.
 
-   Return true iff we received input from any process.  */
+   Return true if we received input from any process.  */
 
 int
 wait_reading_process_output (time_limit, microsecs, read_kbd, do_display,