diff src/process.c @ 1925:3ddb163a9201

* process.c: Make sure we don't miss processes exiting, by having the sigchld handler clear *input_available_clear_time. (wait_reading_process_input): Check for process activity after setting the timeout and calling set_waiting_for_input. (sigchld_handler): If the process which has exited is one we care about, clear *input_available_clear_time. * process.c (process_send_signal): Use TERMIOS functions in preference to BSD ioctls. Some systems attempt to provide the BSD functions for backward compatibility, and get it wrong.
author Jim Blandy <jimb@redhat.com>
date Mon, 22 Feb 1993 14:47:53 +0000
parents dd2e31cbf205
children fc3cdca22f8d
line wrap: on
line diff
--- a/src/process.c	Mon Feb 22 14:46:31 1993 +0000
+++ b/src/process.c	Mon Feb 22 14:47:53 1993 +0000
@@ -1717,23 +1717,6 @@
       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 +1740,33 @@
 	}
 
       /* 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)
+	    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;
+
       /* Wait till there is something to do */
 
       Available = input_wait_mask;
@@ -2326,6 +2332,35 @@
       /* 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 Qnil;
+
+	case SIGQUIT:
+	  tcgetattr (XFASTINT (p->infd), &t);
+  	  send_process (proc, &t.c_cc[VQUIT], 1);
+  	  return Qnil;
+
+  	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 Qnil;
+	}
+
+#else /* ! HAVE_TERMIOS */
+
       /* On Berkeley descendants, the following IOCTL's retrieve the
 	 current control characters.  */
 #if defined (TIOCGLTC) && defined (TIOCGETC)
@@ -2380,6 +2415,7 @@
 	 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 
@@ -2631,6 +2667,7 @@
   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 +2750,11 @@
 	  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 +2772,11 @@
 #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.