aboutsummaryrefslogtreecommitdiffstats
path: root/src/process.c
diff options
context:
space:
mode:
authorJim Blandy1993-02-22 14:47:53 +0000
committerJim Blandy1993-02-22 14:47:53 +0000
commit6be429b16949ffce383dcec596f4edd4b08ad15e (patch)
tree8f2c184d8f4045d4165e589d21afd4904e0d5753 /src/process.c
parentcb09ab7ae148496ba47fe699234a60e6e1a36aa2 (diff)
downloademacs-6be429b16949ffce383dcec596f4edd4b08ad15e.tar.gz
emacs-6be429b16949ffce383dcec596f4edd4b08ad15e.zip
* 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.
Diffstat (limited to 'src/process.c')
-rw-r--r--src/process.c83
1 files changed, 65 insertions, 18 deletions
diff --git a/src/process.c b/src/process.c
index d0d90e90c0b..95be209f94c 100644
--- a/src/process.c
+++ b/src/process.c
@@ -1717,23 +1717,6 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
1717 if (XINT (read_kbd) >= 0) 1717 if (XINT (read_kbd) >= 0)
1718 QUIT; 1718 QUIT;
1719 1719
1720 /* If status of something has changed, and no input is available,
1721 notify the user of the change right away */
1722 if (update_tick != process_tick && do_display)
1723 {
1724 Atemp = input_wait_mask;
1725 EMACS_SET_SECS_USECS (timeout, 0, 0);
1726 if (select (MAXDESC, &Atemp, 0, 0, &timeout) <= 0)
1727 status_notify ();
1728 }
1729
1730 /* Don't wait for output from a non-running process. */
1731 if (wait_proc != 0 && !NILP (wait_proc->raw_status_low))
1732 update_status (wait_proc);
1733 if (wait_proc != 0
1734 && ! EQ (wait_proc->status, Qrun))
1735 break;
1736
1737 /* Compute time from now till when time limit is up */ 1720 /* Compute time from now till when time limit is up */
1738 /* Exit if already run out */ 1721 /* Exit if already run out */
1739 if (time_limit == -1) 1722 if (time_limit == -1)
@@ -1757,10 +1740,33 @@ wait_reading_process_input (time_limit, microsecs, read_kbd, do_display)
1757 } 1740 }
1758 1741
1759 /* Cause C-g and alarm signals to take immediate action, 1742 /* Cause C-g and alarm signals to take immediate action,
1760 and cause input available signals to zero out timeout */ 1743 and cause input available signals to zero out timeout.
1744
1745 It is important that we do this before checking for process
1746 activity. If we get a SIGCHLD after the explicit checks for
1747 process activity, timeout is the only way we will know. */
1761 if (XINT (read_kbd) < 0) 1748 if (XINT (read_kbd) < 0)
1762 set_waiting_for_input (&timeout); 1749 set_waiting_for_input (&timeout);
1763 1750
1751 /* If status of something has changed, and no input is
1752 available, notify the user of the change right away. After
1753 this explicit check, we'll let the SIGCHLD handler zap
1754 timeout to get our attention. */
1755 if (update_tick != process_tick && do_display)
1756 {
1757 Atemp = input_wait_mask;
1758 EMACS_SET_SECS_USECS (timeout, 0, 0);
1759 if (select (MAXDESC, &Atemp, 0, 0, &timeout) <= 0)
1760 status_notify ();
1761 }
1762
1763 /* Don't wait for output from a non-running process. */
1764 if (wait_proc != 0 && !NILP (wait_proc->raw_status_low))
1765 update_status (wait_proc);
1766 if (wait_proc != 0
1767 && ! EQ (wait_proc->status, Qrun))
1768 break;
1769
1764 /* Wait till there is something to do */ 1770 /* Wait till there is something to do */
1765 1771
1766 Available = input_wait_mask; 1772 Available = input_wait_mask;
@@ -2326,6 +2332,35 @@ process_send_signal (process, signo, current_group, nomsg)
2326 /* If possible, send signals to the entire pgrp 2332 /* If possible, send signals to the entire pgrp
2327 by sending an input character to it. */ 2333 by sending an input character to it. */
2328 2334
2335 /* TERMIOS is the latest and bestest, and seems most likely to
2336 work. If the system has it, use it. */
2337#ifdef HAVE_TERMIOS
2338 struct termios t;
2339
2340 switch (signo)
2341 {
2342 case SIGINT:
2343 tcgetattr (XFASTINT (p->infd), &t);
2344 send_process (proc, &t.c_cc[VINTR], 1);
2345 return Qnil;
2346
2347 case SIGQUIT:
2348 tcgetattr (XFASTINT (p->infd), &t);
2349 send_process (proc, &t.c_cc[VQUIT], 1);
2350 return Qnil;
2351
2352 case SIGTSTP:
2353 tcgetattr (XFASTINT (p->infd), &t);
2354#ifdef VSWTCH
2355 send_process (proc, &t.c_cc[VSWTCH], 1);
2356#else
2357 send_process (proc, &t.c_cc[VSUSP], 1);
2358#endif
2359 return Qnil;
2360 }
2361
2362#else /* ! HAVE_TERMIOS */
2363
2329 /* On Berkeley descendants, the following IOCTL's retrieve the 2364 /* On Berkeley descendants, the following IOCTL's retrieve the
2330 current control characters. */ 2365 current control characters. */
2331#if defined (TIOCGLTC) && defined (TIOCGETC) 2366#if defined (TIOCGLTC) && defined (TIOCGETC)
@@ -2380,6 +2415,7 @@ process_send_signal (process, signo, current_group, nomsg)
2380 you'd better be using one of the alternatives above! */ 2415 you'd better be using one of the alternatives above! */
2381#endif /* ! defined (TCGETA) */ 2416#endif /* ! defined (TCGETA) */
2382#endif /* ! defined (TIOCGLTC) && defined (TIOCGETC) */ 2417#endif /* ! defined (TIOCGLTC) && defined (TIOCGETC) */
2418#endif /* ! defined HAVE_TERMIOS */
2383#endif /* ! defined (SIGNALS_VIA_CHARACTERS) */ 2419#endif /* ! defined (SIGNALS_VIA_CHARACTERS) */
2384 2420
2385#ifdef TIOCGPGRP 2421#ifdef TIOCGPGRP
@@ -2631,6 +2667,7 @@ sigchld_handler (signo)
2631 int old_errno = errno; 2667 int old_errno = errno;
2632 Lisp_Object proc; 2668 Lisp_Object proc;
2633 register struct Lisp_Process *p; 2669 register struct Lisp_Process *p;
2670 extern EMACS_TIME *input_available_clear_time;
2634 2671
2635#ifdef BSD4_1 2672#ifdef BSD4_1
2636 extern int sigheld; 2673 extern int sigheld;
@@ -2713,6 +2750,11 @@ sigchld_handler (signo)
2713 if (WIFSIGNALED (w) || WIFEXITED (w)) 2750 if (WIFSIGNALED (w) || WIFEXITED (w))
2714 if (XFASTINT (p->infd)) 2751 if (XFASTINT (p->infd))
2715 FD_CLR (XFASTINT (p->infd), &input_wait_mask); 2752 FD_CLR (XFASTINT (p->infd), &input_wait_mask);
2753
2754 /* Tell wait_reading_process_input that it needs to wake up and
2755 look around. */
2756 if (input_available_clear_time)
2757 EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
2716 } 2758 }
2717 2759
2718 /* There was no asynchronous process found for that id. Check 2760 /* There was no asynchronous process found for that id. Check
@@ -2730,6 +2772,11 @@ sigchld_handler (signo)
2730#else 2772#else
2731 synch_process_death = sys_errlist[WTERMSIG (w)]; 2773 synch_process_death = sys_errlist[WTERMSIG (w)];
2732#endif 2774#endif
2775
2776 /* Tell wait_reading_process_input that it needs to wake up and
2777 look around. */
2778 if (input_available_clear_time)
2779 EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0);
2733 } 2780 }
2734 2781
2735 /* On some systems, we must return right away. 2782 /* On some systems, we must return right away.