(read_process_output): Deactivate the mark.
[bpt/emacs.git] / src / process.c
index 1e1e2e3..91e411e 100644 (file)
@@ -1,11 +1,11 @@
 /* Asynchronous subprocess control for GNU Emacs.
-   Copyright (C) 1985, 1986, 1987, 1988, 1992 Free Software Foundation, Inc.
+   Copyright (C) 1985, 1986, 1987, 1988, 1993 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 1, or (at your option)
+the Free Software Foundation; either version 2, or (at your option)
 any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
@@ -71,7 +71,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "termhooks.h"
 #include "termopts.h"
 #include "commands.h"
-#include "dispextern.h"
+#include "frame.h"
 
 Lisp_Object Qrun, Qstop, Qsignal, Qopen, Qclosed;
 /* Qexit is declared and initialized in eval.c.  */
@@ -110,7 +110,7 @@ static Lisp_Object stream_process;
 
 #ifndef VMS
 #ifndef WAITTYPE
-#if !defined (BSD) && !defined (UNIPLUS) && !defined (STRIDE) && !(defined (HPUX) && !defined (NOMULTIPLEJOBS)) && !defined (HAVE_WAIT_HEADER)
+#if (!defined (BSD) && !defined (UNIPLUS) && !defined (STRIDE) && !(defined (HPUX) && !defined (NOMULTIPLEJOBS)) && !defined (HAVE_WAIT_HEADER)) || defined (LINUX)
 #define WAITTYPE int
 #define WIFSTOPPED(w) ((w&0377) == 0177)
 #define WIFSIGNALED(w) ((w&0377) != 0177 && (w&~0377) == 0)
@@ -159,12 +159,14 @@ static Lisp_Object stream_process;
 #endif /* BSD or UNIPLUS or STRIDE */
 #endif /* no WAITTYPE */
 #else /* VMS */
-
-/* For the CMU PTY driver + */
-#define DCL_PROMPT "$ "
-/* This is a hack.  I have no idea what needs to go here, but this */
-/* will get it to compile.  We can fix it later.  rbr */
 #define WAITTYPE int
+#define WIFSTOPPED(w) 0
+#define WIFSIGNALED(w) 0
+#define WIFEXITED(w) ((w) != -1)
+#define WRETCODE(w) (w)
+#define WSTOPSIG(w) (w)
+#define WCOREDUMP(w) 0
+#define WTERMSIG(w) (w)
 #include <ssdef.h>
 #include <iodef.h>
 #include <clidef.h>
@@ -177,7 +179,9 @@ extern char *sys_errlist[];
 
 #ifndef VMS
 #ifndef BSD4_1
+#ifndef LINUX
 extern char *sys_siglist[];
+#endif
 #else
 char *sys_siglist[] =
   {
@@ -211,13 +215,6 @@ char *sys_siglist[] =
 #endif
 #endif /* VMS */
 
-#ifdef vipc
-
-#include "vipc.h"
-extern int comm_server;
-extern int net_listen_address;
-#endif /* vipc */
-
 /* t means use pty, nil means use a pipe,
    maybe other values to come.  */
 Lisp_Object Vprocess_connection_type;
@@ -238,7 +235,11 @@ int update_tick;
 /* We could get this from param.h, but better not to depend on finding that.
    And better not to risk that it might define other symbols used in this
    file.  */
+#ifdef FD_SETSIZE
+#define MAXDESC FD_SETSIZE
+#else
 #define MAXDESC 64
+#endif
 #define SELECT_TYPE fd_set
 #else /* no FD_SET */
 #define MAXDESC 32
@@ -364,7 +365,7 @@ status_message (status)
     {
       if (code == 0)
        return build_string ("finished\n");
-      string = Fint_to_string (make_number (code));
+      string = Fnumber_to_string (make_number (code));
       string2 = build_string (coredump ? " (core dumped)\n" : "\n");
       return concat2 (build_string ("exited abnormally with code "),
                      concat2 (string, string2));
@@ -449,7 +450,7 @@ allocate_pty ()
            if (access (pty_name, 6) != 0)
              {
                close (fd);
-#ifndef IRIS
+#if !defined(IRIS) && !defined(__sgi)
                continue;
 #else
                return -1;
@@ -987,7 +988,7 @@ Remaining arguments are strings to give program as arguments.")
 
     current_dir = 
       expand_and_dir_to_file
-       (Funhandled_file_name_directory (current_dir, Qnil));
+       (Funhandled_file_name_directory (current_dir), Qnil);
     if (NILP (Ffile_accessible_directory_p (current_dir)))
       report_file_error ("Setting current directory",
                         Fcons (current_buffer->directory, Qnil));
@@ -1039,7 +1040,7 @@ Remaining arguments are strings to give program as arguments.")
   if (new_argv[0][0] != '/')
     {
       tem = Qnil;
-      openp (Vexec_path, program, "", &tem, 1);
+      openp (Vexec_path, program, EXEC_SUFFIXES, &tem, 1);
       if (NILP (tem))
        report_file_error ("Searching for program", Fcons (program, Qnil));
       new_argv[0] = XSTRING (tem)->data;
@@ -1258,8 +1259,10 @@ create_process (process, new_argv, current_dir)
        setsid ();
 #ifdef TIOCSCTTY
        /* Make the pty's terminal the controlling terminal.  */
-       if (pty_flag && (ioctl (xforkin, TIOCSCTTY, 0) < 0))
-         abort ();
+       if (pty_flag)
+         /* We ignore the return value
+            because faith@cs.unc.edu says that is necessary on Linux.  */
+         ioctl (xforkin, TIOCSCTTY, 0);
 #endif
 #else /* not HAVE_SETSID */
 #ifdef USG
@@ -1453,8 +1456,13 @@ Fourth arg SERVICE is name of the service desired, or an integer\n\
       host_info.h_name = 0;
       host_info.h_aliases = 0;
       host_info.h_addrtype = AF_INET;
-      host_info.h_addr_list  =  &(addr_list[0]);
-      addr_list[0] = (char*)(&numeric_addr);
+#ifdef h_addr
+      /* Older machines have only one address slot called h_addr.
+        Newer machines have h_addr_list, but #define h_addr to
+        be its first element.  */
+      host_info.h_addr_list = &(addr_list[0]);
+#endif
+      host_info.h_addr = (char*)(&numeric_addr);
       addr_list[1] = 0;
       host_info.h_length = strlen (addr_list[0]);
     }
@@ -1534,7 +1542,7 @@ deactivate_process (proc)
       {
        VMS_PROC_STUFF *get_vms_process_pointer (), *vs;
        sys$dassgn (outchannel);
-       vs = get_vms_process_pointer (p->pid)
+       vs = get_vms_process_pointer (p->pid);
        if (vs)
          give_back_vms_process_stuff (vs);
       }
@@ -1655,11 +1663,16 @@ static int waiting_for_user_input_p;
      zero for no limit, or
      -1 means gobble data immediately available but don't wait for any.
 
+   microsecs is:
+     an additional duration to wait (if time_limit is greater than
+     zero), specified in millisec.
+
    read_kbd is a lisp value:
      0 to ignore keyboard input, or
      1 to return when input is available, or
-     -1 means caller will actually read the input, so don't throw to
+     -1 meaning caller will actually read the input, so don't throw to
        the quit handler, or
+     a cons cell, meaning wait wait until its car is non-nil, or
      a process object, meaning wait until something arrives from that
        process.  The return value is true iff we read some input from
        that process.
@@ -1686,6 +1699,7 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
   int wait_channel = 0;
   struct Lisp_Process *wait_proc = 0;
   int got_some_input = 0;
+  Lisp_Object *wait_for_cell = 0;
 
   FD_ZERO (&Available);
 
@@ -1698,6 +1712,13 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
       XFASTINT (read_kbd) = 0;
     }
 
+  /* If waiting for non-nil in a cell, record where.  */
+  if (XTYPE (read_kbd) == Lisp_Cons)
+    {
+      wait_for_cell = &XCONS (read_kbd)->car;
+      XFASTINT (read_kbd) = 0;
+    }
+
   waiting_for_user_input_p = XINT (read_kbd);
 
   /* Since we may need to wait several times,
@@ -1717,23 +1738,6 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
       if (XINT (read_kbd) >= 0)
        QUIT;
 
-      /* If status of something has changed, and no input is available,
-        notify the user of the change right away */
-      if (update_tick != process_tick && do_display)
-       {
-         Atemp = input_wait_mask;
-         EMACS_SET_SECS_USECS (timeout, 0, 0);
-         if (select (MAXDESC, &Atemp, 0, 0, &timeout) <= 0)
-           status_notify ();
-       }
-
-      /* Don't wait for output from a non-running process.  */
-      if (wait_proc != 0 && !NILP (wait_proc->raw_status_low))
-       update_status (wait_proc);
-      if (wait_proc != 0
-         && ! EQ (wait_proc->status, Qrun))
-       break;
-
       /* Compute time from now till when time limit is up */
       /* Exit if already run out */
       if (time_limit == -1)
@@ -1757,10 +1761,41 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
        }
 
       /* Cause C-g and alarm signals to take immediate action,
-        and cause input available signals to zero out timeout */
+        and cause input available signals to zero out timeout.
+
+        It is important that we do this before checking for process
+        activity.  If we get a SIGCHLD after the explicit checks for
+        process activity, timeout is the only way we will know.  */
       if (XINT (read_kbd) < 0)
        set_waiting_for_input (&timeout);
 
+      /* If status of something has changed, and no input is
+        available, notify the user of the change right away.  After
+        this explicit check, we'll let the SIGCHLD handler zap
+        timeout to get our attention.  */
+      if (update_tick != process_tick && do_display)
+       {
+         Atemp = input_wait_mask;
+         EMACS_SET_SECS_USECS (timeout, 0, 0);
+         if (select (MAXDESC, &Atemp, 0, 0, &timeout) <= 0)
+           {
+             /* It's okay for us to do this and then continue with
+                the loop, since timeout has already been zeroed out. */
+             clear_waiting_for_input ();
+             status_notify ();
+           }
+       }
+
+      /* Don't wait for output from a non-running process.  */
+      if (wait_proc != 0 && !NILP (wait_proc->raw_status_low))
+       update_status (wait_proc);
+      if (wait_proc != 0
+         && ! EQ (wait_proc->status, Qrun))
+       {
+         clear_waiting_for_input ();
+         break;
+       }
+
       /* Wait till there is something to do */
 
       Available = input_wait_mask;
@@ -1827,9 +1862,15 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
          else
            error("select error: %s", sys_errlist[xerrno]);
        }
-#ifdef sun
+#if defined(sun) && !defined(USG5_4)
       else if (nfds > 0 && FD_ISSET (0, &Available) && interrupt_input)
-       /* System sometimes fails to deliver SIGIO.  */
+       /* System sometimes fails to deliver SIGIO.
+
+          David J. Mackenzie says that Emacs doesn't compile under
+          Solaris if this code is enabled, thus the USG5_4 in the CPP
+          conditional.  "I haven't noticed any ill effects so far.
+          If you find a Solaris expert somewhere, they might know
+          better." */
        kill (getpid (), SIGIO);
 #endif
 
@@ -1838,6 +1879,14 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
         to give it higher priority than subprocesses */
 
       if (XINT (read_kbd) && detect_input_pending ())
+       {
+         swallow_events ();
+         if (detect_input_pending ())
+           break;
+       }
+
+      /* Exit now if the cell we're waiting for became non-nil.  */
+      if (wait_for_cell && ! NILP (*wait_for_cell))
        break;
 
 #ifdef SIGIO
@@ -1846,23 +1895,10 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
         In that case, there really is no input and no SIGIO,
         but select says there is input.  */
 
-      /*
-       if (XINT (read_kbd) && interrupt_input && (Available & fileno (stdin)))
-       */
       if (XINT (read_kbd) && interrupt_input && (FD_ISSET (fileno (stdin), &Available)))
        kill (0, SIGIO);
 #endif
 
-#ifdef vipc
-      /* Check for connection from other process */
-
-      if (Available & ChannelMask (comm_server))
-       {
-         Available &= ~(ChannelMask (comm_server));
-         create_commchan ();
-       }
-#endif /* vipc */
-
       if (! wait_proc)
        got_some_input |= nfds > 0;
 
@@ -1891,24 +1927,6 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
              if (NILP (proc))
                continue;
 
-#ifdef vipc
-             /* It's a command channel */
-             if (!NILP (XPROCESS (proc)->command_channel_p))
-               {
-                 ProcessCommChan (channel, proc);
-                 if (NILP (XPROCESS (proc)->command_channel_p))
-                   {
-                     /* It has ceased to be a command channel! */
-                     int bytes_available;
-                     if (ioctl (channel, FIONREAD, &bytes_available) < 0)
-                       bytes_available = 0;
-                     if (bytes_available)
-                       FD_SET (channel, &Available);
-                   }
-                 continue;
-               }
-#endif                         /* vipc */
-
              /* Read data from the process, starting with our
                 buffered-ahead character if we have one.  */
 
@@ -2057,9 +2075,25 @@ read_process_output (proc, channel)
         hitting ^G when a filter happens to be running won't screw
         it up.  */
       int count = specpdl_ptr - specpdl;
+      Lisp_Object odeactivate;
+
+      odeactivate = Vdeactivate_mark;
+
       specbind (Qinhibit_quit, Qt);
       call2 (outstream, proc, make_string (chars, nchars));
 
+      /* Deactivate the mark now, so it doesn't happen
+        *after* the following command.  */
+      if (!NILP (current_buffer->mark_active))
+       {
+         if (!NILP (Vdeactivate_mark) && !NILP (Vtransient_mark_mode))
+           {
+             current_buffer->mark_active = Qnil;
+             call1 (Vrun_hooks, intern ("deactivate-mark-hook"));
+           }
+       }
+      Vdeactivate_mark = odeactivate;
+
 #ifdef VMS
       start_vms_process_read (vs);
 #endif
@@ -2072,6 +2106,9 @@ read_process_output (proc, channel)
     {
       Lisp_Object old_read_only;
       Lisp_Object old_begv, old_zv;
+      Lisp_Object odeactivate;
+
+      odeactivate = Vdeactivate_mark;
 
       Fset_buffer (p->buffer);
       opoint = point;
@@ -2116,6 +2153,19 @@ read_process_output (proc, channel)
       if (XFASTINT (old_begv) != BEGV || XFASTINT (old_zv) != ZV)
        Fnarrow_to_region (old_begv, old_zv);
 
+      /* Deactivate the mark now, so it doesn't happen
+        *after* the following command.  */
+      if (!NILP (current_buffer->mark_active))
+       {
+         if (!NILP (Vdeactivate_mark) && !NILP (Vtransient_mark_mode))
+           {
+             current_buffer->mark_active = Qnil;
+             call1 (Vrun_hooks, intern ("deactivate-mark-hook"));
+           }
+       }
+
+      Vdeactivate_mark = odeactivate;
+
       current_buffer->read_only = old_read_only;
       SET_PT (opoint);
       set_buffer_internal (old);
@@ -2326,6 +2376,35 @@ process_send_signal (process, signo, current_group, nomsg)
       /* If possible, send signals to the entire pgrp
         by sending an input character to it.  */
 
+      /* TERMIOS is the latest and bestest, and seems most likely to
+         work.  If the system has it, use it.  */
+#ifdef HAVE_TERMIOS
+      struct termios t;
+
+      switch (signo)
+       {
+       case SIGINT:
+         tcgetattr (XFASTINT (p->infd), &t);
+         send_process (proc, &t.c_cc[VINTR], 1);
+         return;
+
+       case SIGQUIT:
+         tcgetattr (XFASTINT (p->infd), &t);
+         send_process (proc, &t.c_cc[VQUIT], 1);
+         return;
+
+       case SIGTSTP:
+         tcgetattr (XFASTINT (p->infd), &t);
+#ifdef VSWTCH
+         send_process (proc, &t.c_cc[VSWTCH], 1);
+#else
+         send_process (proc, &t.c_cc[VSUSP], 1);
+#endif
+         return;
+       }
+
+#else /* ! HAVE_TERMIOS */
+
       /* On Berkeley descendants, the following IOCTL's retrieve the
         current control characters.  */
 #if defined (TIOCGLTC) && defined (TIOCGETC)
@@ -2380,6 +2459,7 @@ process_send_signal (process, signo, current_group, nomsg)
         you'd better be using one of the alternatives above!  */
 #endif /* ! defined (TCGETA) */
 #endif /* ! defined (TIOCGLTC) && defined (TIOCGETC) */
+#endif /* ! defined HAVE_TERMIOS */
 #endif /* ! defined (SIGNALS_VIA_CHARACTERS) */
 
 #ifdef TIOCGPGRP 
@@ -2557,6 +2637,13 @@ nil, indicating the current buffer's process.")
   Lisp_Object proc;
 
   proc = get_process (process);
+
+  /* Make sure the process is really alive.  */
+  if (! NILP (XPROCESS (proc)->raw_status_low))
+    update_status (XPROCESS (proc));
+  if (! EQ (XPROCESS (proc)->status, Qrun))
+    error ("Process %s not running", XSTRING (XPROCESS (proc)->name)->data);
+
   /* Sending a zero-length record is supposed to mean eof
      when TIOCREMOTE is turned on.  */
 #ifdef DID_REMOTE
@@ -2573,7 +2660,7 @@ nil, indicating the current buffer's process.")
   else
     {
       close (XPROCESS (proc)->outfd);
-      XFASTINT (XPROCESS (proc)->outfd) = open ("/dev/null", O_WRONLY);
+      XFASTINT (XPROCESS (proc)->outfd) = open (NULL_DEVICE, O_WRONLY);
     }
 #endif /* VMS */
 #endif /* did not do TOICREMOTE */
@@ -2631,6 +2718,7 @@ sigchld_handler (signo)
   int old_errno = errno;
   Lisp_Object proc;
   register struct Lisp_Process *p;
+  extern EMACS_TIME *input_available_clear_time;
 
 #ifdef BSD4_1
   extern int sigheld;
@@ -2713,6 +2801,11 @@ sigchld_handler (signo)
          if (WIFSIGNALED (w) || WIFEXITED (w))
            if (XFASTINT (p->infd))
              FD_CLR (XFASTINT (p->infd), &input_wait_mask);
+
+         /* Tell wait_reading_process_input that it needs to wake up and
+            look around.  */
+         if (input_available_clear_time)
+           EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
        }
 
        /* There was no asynchronous process found for that id.  Check
@@ -2730,6 +2823,11 @@ sigchld_handler (signo)
 #else
            synch_process_death = sys_errlist[WTERMSIG (w)];
 #endif
+
+         /* Tell wait_reading_process_input that it needs to wake up and
+            look around.  */
+         if (input_available_clear_time)
+           EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
        }
 
       /* On some systems, we must return right away.
@@ -3120,6 +3218,8 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
        break;
     }
 
+  start_polling ();
+
   return 0;
 }