Commit 6be429b1 authored by Jim Blandy's avatar Jim Blandy

* 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.
parent cb09ab7a
......@@ -1717,23 +1717,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 +1740,33 @@ 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)
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 @@ 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 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 @@ 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
......@@ -2631,6 +2667,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 +2750,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 +2772,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.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment