Mercurial > emacs
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.