comparison src/signal.c @ 428:3ecd8885ac67 r21-2-22

Import from CVS: tag r21-2-22
author cvs
date Mon, 13 Aug 2007 11:28:15 +0200
parents
children abe6d1db359e
comparison
equal deleted inserted replaced
427:0a0253eac470 428:3ecd8885ac67
1 /* Handling asynchronous signals.
2 Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
3 Copyright (C) 1995, 1996 Ben Wing.
4
5 This file is part of XEmacs.
6
7 XEmacs is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
10 later version.
11
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with XEmacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22 /* Synched up with: Not synched with FSF. Split out of keyboard.c. */
23
24 #include <config.h>
25 #include "lisp.h"
26
27 #include "console.h"
28 #include "events.h" /* for signal_fake_event() */
29 #include "frame.h"
30 #include "sysdep.h"
31 #include "syssignal.h"
32 #include "systime.h"
33
34 #ifdef HAVE_UNISTD_H
35 #include <unistd.h>
36 #endif
37 #include <errno.h>
38
39 /* Set to 1 when a quit-check signal (either a SIGIO interrupt or
40 the asynch. timeout for poll-for-quit) occurs. The QUITP
41 macro may look at this. */
42 volatile int quit_check_signal_happened;
43
44 /* Count of the number of times a quit-check signal has occurred.
45 Some stuff in event-Xt.c looks at this. */
46 volatile int quit_check_signal_tick_count;
47
48 /* Set to 1 when a SIGINT (or SIGQUIT) interrupt is processed.
49 maybe_read_quit_event() looks at this. */
50 volatile int sigint_happened;
51
52 /* Set to 1 when an asynch. timeout signal occurs. */
53 static volatile int alarm_happened;
54
55 /* This is used to synchronize setting the waiting_for_user_input_p
56 flag. */
57 static volatile int alarm_happened_while_emacs_was_blocking;
58
59 /* See check_quit() for when this is set. */
60 int dont_check_for_quit;
61
62 #if !defined (SIGIO) && !defined (DONT_POLL_FOR_QUIT)
63 int poll_for_quit_id;
64 #endif
65
66 #if defined(HAVE_UNIX_PROCESSES) && !defined(SIGCHLD)
67 int poll_for_sigchld_id;
68 #endif
69
70 /* This variable is used to communicate to a lisp
71 process-filter/sentinel/asynchronous callback (via the function
72 Fwaiting_for_user_input_p below) whether XEmacs was waiting for
73 user-input when that process-filter was called. */
74 static int waiting_for_user_input_p;
75
76 static int interrupts_slowed_down;
77
78 #define SLOWED_DOWN_INTERRUPTS_SECS 15
79 #define NORMAL_QUIT_CHECK_TIMEOUT_MSECS 250
80 #define NORMAL_SIGCHLD_CHECK_TIMEOUT_MSECS 250
81
82 /* Used so that signals can break out of system calls that aren't
83 naturally interruptible. */
84
85 JMP_BUF break_system_call_jump;
86 volatile int can_break_system_calls;
87
88
89 /**********************************************************************/
90 /* Asynchronous timeout functions */
91 /**********************************************************************/
92
93 /* The pending timers are stored in an ordered list, where the first timer
94 on the list is the first one to fire. Times recorded here are
95 absolute. */
96 static struct low_level_timeout *async_timer_queue;
97
98 /* Nonzero means async timers are temporarily suppressed. */
99 static int async_timer_suppress_count;
100
101 static void
102 set_one_shot_timer (EMACS_TIME interval)
103 {
104 #ifdef HAVE_SETITIMER
105 struct itimerval it;
106 it.it_value = interval;
107 EMACS_SET_SECS_USECS (it.it_interval, 0, 0);
108 setitimer (ITIMER_REAL, &it, 0);
109 #else
110 int secs;
111 EMACS_TIME_TO_INT (interval, secs);
112 alarm (secs);
113 #endif
114 }
115
116 static void
117 reset_interval_timer (void)
118 {
119 EMACS_TIME interval;
120
121 /* Get the interval to set. If an interval is available,
122 make sure it's not zero (this is a valid return, but it will
123 cause the timer to get disabled, so convert it to a very short
124 time). */
125 if (get_low_level_timeout_interval (async_timer_queue, &interval))
126 {
127 if (EMACS_SECS (interval) == 0 && EMACS_USECS (interval) == 0)
128 EMACS_SET_USECS (interval, 1);
129 }
130 else
131 /* A time of 0 means "disable". */
132 EMACS_SET_SECS_USECS (interval, 0, 0);
133
134 set_one_shot_timer (interval);
135 }
136
137 int
138 event_stream_add_async_timeout (EMACS_TIME thyme)
139 {
140 int id = add_low_level_timeout (&async_timer_queue, thyme);
141
142 /* If this timeout is at the head of the queue, then we need to
143 set the timer right now for this timeout. Otherwise, things
144 are fine as-is; after the timers ahead of us are signalled,
145 the timer will be set for us. */
146
147 if (async_timer_queue->id == id)
148 reset_interval_timer ();
149
150 return id;
151 }
152
153 void
154 event_stream_remove_async_timeout (int id)
155 {
156 int first = (async_timer_queue && async_timer_queue->id == id);
157 remove_low_level_timeout (&async_timer_queue, id);
158
159 /* If we removed the timeout from the head of the queue, then
160 we need to reset the interval timer right now. */
161 if (first)
162 reset_interval_timer ();
163 }
164
165 /* Handle an alarm once each second and read pending input
166 so as to handle a C-g if it comes in. */
167
168 static SIGTYPE
169 alarm_signal (int signo)
170 {
171 if (interrupts_slowed_down)
172 {
173 something_happened = 1; /* tell QUIT to wake up */
174 /* we are in "slowed-down interrupts" mode; the only alarm
175 happening here is the slowed-down quit-check alarm, so
176 we set this flag.
177
178 Do NOT set alarm_happened, because we don't want anyone
179 looking at the timeout queue. We didn't set it and
180 it needs to stay the way it is. */
181 quit_check_signal_happened = 1;
182
183 #ifdef WINDOWSNT
184 can_break_system_calls = 0;
185 #else
186 /* can_break_system_calls is set when we want to break out of
187 non-interruptible system calls. */
188 if (can_break_system_calls)
189 {
190 /* reset the flag for safety and such. Do this *before*
191 unblocking or reestablishing the signal to avoid potential
192 race conditions. */
193 can_break_system_calls = 0;
194 EMACS_UNBLOCK_SIGNAL (signo);
195 EMACS_REESTABLISH_SIGNAL (signo, alarm_signal);
196 LONGJMP (break_system_call_jump, 0);
197 }
198 #endif
199
200 EMACS_REESTABLISH_SIGNAL (signo, alarm_signal);
201 SIGRETURN;
202 }
203
204 something_happened = 1; /* tell QUIT to wake up */
205 alarm_happened = 1;
206 if (emacs_is_blocking)
207 alarm_happened_while_emacs_was_blocking = 1;
208 /* #### This is for QUITP. When it is run, it may not be the
209 place to do arbitrary stuff like run asynch. handlers, but
210 it needs to know whether the poll-for-quit asynch. timeout
211 went off. Rather than put the code in to compute this
212 specially, we just set this flag. Should fix this. */
213 quit_check_signal_happened = 1;
214
215 #ifdef HAVE_UNIXOID_EVENT_LOOP
216 signal_fake_event ();
217 #endif
218
219 EMACS_REESTABLISH_SIGNAL (signo, alarm_signal);
220 SIGRETURN;
221 }
222
223 static void
224 init_async_timeouts (void)
225 {
226 signal (SIGALRM, alarm_signal);
227 async_timer_suppress_count = 0;
228 }
229
230 /* Turn off async timeouts. */
231
232 static void
233 stop_async_timeouts (void)
234 {
235 if (async_timer_suppress_count == 0)
236 {
237 /* If timer was on, turn it off. */
238 EMACS_TIME thyme;
239 EMACS_SET_SECS_USECS (thyme, 0, 0);
240 set_one_shot_timer (thyme);
241 }
242 async_timer_suppress_count++;
243 }
244
245 /* Turn on async timeouts again. */
246
247 static void
248 start_async_timeouts (void)
249 {
250 assert (async_timer_suppress_count > 0);
251 async_timer_suppress_count--;
252 if (async_timer_suppress_count == 0)
253 {
254 /* Some callers turn off async timeouts and then use the alarm
255 for their own purposes; so reinitialize everything. */
256 signal (SIGALRM, alarm_signal);
257 reset_interval_timer ();
258 }
259 }
260
261 /* Some functions don't like being interrupted with SIGALRM or SIGIO.
262 Previously we were calling stop_interrupts() / start_interrupts(),
263 but then if the program hangs in one of those functions, e.g.
264 waiting for a connect(), we're really screwed. So instead we
265 just "slow them down". We do this by disabling all interrupts
266 and then installing a timer of length fairly large, like 5 or
267 10 secs. That way, any "legitimate" connections (which should
268 take a fairly short amount of time) go through OK, but we can
269 interrupt bogus ones. */
270
271 void
272 slow_down_interrupts (void)
273 {
274 EMACS_TIME thyme;
275
276 /* We have to set the flag *before* setting the slowed-down timer,
277 to avoid a race condition -- if the signal occurs between the
278 call to set_one_shot_timer() and the setting of this flag,
279 alarm_happened will get set, which will be a Bad Thing if
280 there were no timeouts on the queue. */
281 interrupts_slowed_down++;
282 if (interrupts_slowed_down == 1)
283 {
284 stop_interrupts ();
285 EMACS_SET_SECS_USECS (thyme, SLOWED_DOWN_INTERRUPTS_SECS, 0);
286 set_one_shot_timer (thyme);
287 }
288 }
289
290 void
291 speed_up_interrupts (void)
292 {
293 if (interrupts_slowed_down > 0)
294 {
295 start_interrupts ();
296 /* Change this flag AFTER fiddling with interrupts, for the same
297 race-condition reasons as above. */
298 interrupts_slowed_down--;
299 }
300 }
301
302 static void
303 handle_alarm_going_off (void)
304 {
305 int interval_id;
306
307 /* If asynch. timeouts are blocked, then don't do anything now,
308 but make this function get called again next QUIT.
309
310 #### This is a bit inefficient because there will be function call
311 overhead each time QUIT occurs. */
312
313 if (!NILP (Vinhibit_quit))
314 {
315 something_happened = 1;
316 alarm_happened = 1;
317 return;
318 }
319
320 interval_id = pop_low_level_timeout (&async_timer_queue, 0);
321
322 reset_interval_timer ();
323 if (alarm_happened_while_emacs_was_blocking)
324 {
325 alarm_happened_while_emacs_was_blocking = 0;
326 waiting_for_user_input_p = 1;
327 }
328 event_stream_deal_with_async_timeout (interval_id);
329 waiting_for_user_input_p = 0;
330 }
331
332 #ifdef HAVE_SETITIMER
333 unsigned int
334 alarm (unsigned int howlong)
335 {
336 struct itimerval old_it, new_it;
337
338 /* If alarm() gets called when polling isn't disabled, it can mess
339 up the periodic timer. */
340 assert (async_timer_suppress_count > 0);
341
342 new_it.it_value.tv_sec = howlong;
343 new_it.it_value.tv_usec = 0;
344 new_it.it_interval.tv_sec = 0;
345 new_it.it_interval.tv_usec = 0;
346 setitimer (ITIMER_REAL, &new_it, &old_it);
347
348 /* Never return zero if there was a timer outstanding. */
349 return old_it.it_value.tv_sec + (old_it.it_value.tv_usec > 0 ? 1 : 0);
350 }
351 #endif
352
353 DEFUN ("waiting-for-user-input-p", Fwaiting_for_user_input_p, 0, 0, 0, /*
354 Return non-nil if XEmacs is waiting for input from the user.
355 This is intended for use by asynchronous timeout callbacks and by
356 asynchronous process output filters and sentinels (not yet implemented
357 in XEmacs). It will always be nil if XEmacs is not inside of
358 an asynchronous timeout or process callback.
359 */
360 ())
361 {
362 return waiting_for_user_input_p ? Qt : Qnil;
363 }
364
365
366 /**********************************************************************/
367 /* Control-G checking */
368 /**********************************************************************/
369
370 /* Set this for debugging, to have a way to get out */
371 int stop_character; /* #### not currently implemented */
372
373 /* This routine is called in response to a SIGINT or SIGQUIT.
374 On TTY's, one of these two signals will get generated in response
375 to C-g. (When running under X, C-g is handled using the SIGIO
376 handler, which sets a flag telling the QUIT macro to scan the
377 unread events for a ^G.)
378
379 Otherwise it sets the Lisp variable quit-flag not-nil.
380 This causes eval to throw, when it gets a chance.
381 If quit-flag is already non-nil, it stops the job right away. */
382
383 static SIGTYPE
384 interrupt_signal (int sig)
385 {
386 /* This function can call lisp */
387 /* #### we should NOT be calling lisp from a signal handler, boys
388 and girls */
389 /* Must preserve main program's value of errno. */
390 int old_errno = errno;
391
392 EMACS_REESTABLISH_SIGNAL (sig, interrupt_signal);
393
394 /* with the macroized error-checking stuff, the garbage below
395 may mess things up because XCONSOLE() and such can use and
396 change global vars. */
397 #if ! (defined (ERROR_CHECK_TYPECHECK) && defined (MACROIZE_ERROR_CHECKING))
398 if (sigint_happened && CONSOLEP (Vcontrolling_terminal) &&
399 CONSOLE_LIVE_P (XCONSOLE (Vcontrolling_terminal)) &&
400 !emacs_is_blocking)
401 {
402 char c;
403 fflush (stdout);
404 reset_initial_console ();
405 EMACS_UNBLOCK_SIGNAL (sig);
406 #ifdef SIGTSTP /* Support possible in later USG versions */
407 /*
408 * On systems which can suspend the current process and return to the original
409 * shell, this command causes the user to end up back at the shell.
410 * The "Auto-save" and "Abort" questions are not asked until
411 * the user elects to return to emacs, at which point he can save the current
412 * job and either dump core or continue.
413 */
414 sys_suspend ();
415 #else
416 /* Perhaps should really fork an inferior shell?
417 But that would not provide any way to get back
418 to the original shell, ever. */
419 stdout_out ("No support for stopping a process on this operating system;\n");
420 stdout_out ("you can continue or abort.\n");
421 #endif /* not SIGTSTP */
422 stdout_out ("Auto-save? (y or n) ");
423 fflush (stdout);
424 if (((c = getc (stdin)) & ~040) == 'Y')
425 Fdo_auto_save (Qnil, Qnil);
426 while (c != '\n')
427 c = getc (stdin);
428 stdout_out ("Abort (and dump core)? (y or n) ");
429 fflush (stdout);
430 if (((c = getc (stdin)) & ~040) == 'Y')
431 abort ();
432 while (c != '\n')
433 c = getc (stdin);
434 stdout_out ("Continuing...\n");
435 fflush (stdout);
436 reinit_initial_console ();
437 MARK_FRAME_CHANGED (XFRAME (DEVICE_SELECTED_FRAME
438 (XDEVICE (CONSOLE_SELECTED_DEVICE
439 (XCONSOLE
440 (Vcontrolling_terminal))))));
441 }
442 else
443 #endif /* ! (defined (ERROR_CHECKING) && defined (MACROIZE_ERROR_CHECKING)) */
444 {
445 /* Else request quit when it's safe */
446 Vquit_flag = Qt;
447 sigint_happened = 1;
448 #ifdef HAVE_UNIXOID_EVENT_LOOP
449 signal_fake_event ();
450 #endif
451 }
452 errno = old_errno;
453 SIGRETURN;
454 }
455
456 static Lisp_Object
457 restore_dont_check_for_quit (Lisp_Object val)
458 {
459 dont_check_for_quit = XINT (val);
460 return Qnil;
461 }
462
463 void
464 begin_dont_check_for_quit (void)
465 {
466 specbind (Qinhibit_quit, Qt);
467 record_unwind_protect (restore_dont_check_for_quit,
468 make_int (dont_check_for_quit));
469 dont_check_for_quit = 1;
470 }
471
472 /* The effect of this function is to set Vquit_flag if the user pressed
473 ^G and discard the ^G, so as to not notice the same ^G again. */
474 int
475 check_quit (void)
476 {
477 /* dont_check_for_quit is set in two circumstances:
478
479 (1) when we are in the process of changing the window
480 configuration. The frame might be in an inconsistent state,
481 which will cause assertion failures if we check for QUIT.
482
483 (2) when we are reading events, and want to read the C-g
484 as an event. The normal check for quit will discard the C-g,
485 which would be bad.
486
487 #### C-g is still often read as quit, e.g. if you type C-x C-g
488 (the C-g happens during the sit-for in maybe_echo_keys(); even
489 if we attempt to inhibit quit here, there is still a check
490 later on for QUIT. To fix this properly requires a fairly
491 substantial overhaul of the quit-checking code, which is
492 probably not worth it.)
493
494 We should *not* conditionalize on Vinhibit_quit, or
495 critical-quit (Control-Shift-G) won't work right. */
496
497 if (dont_check_for_quit)
498 return 0;
499
500 if (quit_check_signal_happened)
501 {
502 quit_check_signal_happened = 0;
503 event_stream_quit_p ();
504 return 1;
505 }
506 else
507 return 0;
508 }
509
510 int
511 check_what_happened (void) /* called from QUIT when
512 something_happened gets set */
513 {
514 something_happened = 0;
515 if (alarm_happened)
516 {
517 alarm_happened = 0;
518 handle_alarm_going_off ();
519 }
520 return check_quit ();
521 }
522
523
524
525 void
526 init_poll_for_quit (void)
527 {
528 #if !defined (SIGIO) && !defined (DONT_POLL_FOR_QUIT)
529 /* Check for C-g every 1/4 of a second.
530
531 #### This is just a guess. Some investigation will have to be
532 done to see what the best value is. The best value is the
533 smallest possible value that doesn't cause a significant amount
534 of running time to be spent in C-g checking. */
535 if (!poll_for_quit_id)
536 poll_for_quit_id =
537 event_stream_generate_wakeup (NORMAL_QUIT_CHECK_TIMEOUT_MSECS,
538 NORMAL_QUIT_CHECK_TIMEOUT_MSECS,
539 Qnil, Qnil, 1);
540 #endif /* not SIGIO and not DONT_POLL_FOR_QUIT */
541 }
542
543 void
544 reset_poll_for_quit (void)
545 {
546 #if !defined (SIGIO) && !defined (DONT_POLL_FOR_QUIT)
547 if (poll_for_quit_id)
548 {
549 event_stream_disable_wakeup (poll_for_quit_id, 1);
550 poll_for_quit_id = 0;
551 }
552 #endif /* not SIGIO and not DONT_POLL_FOR_QUIT */
553 }
554
555 #if defined(HAVE_UNIX_PROCESSES) && !defined(SIGCHLD)
556
557 static void
558 init_poll_for_sigchld (void)
559 {
560 /* Check for terminated processes every 1/4 of a second.
561
562 #### This is just a guess. Some investigation will have to be
563 done to see what the best value is. The best value is the
564 smallest possible value that doesn't cause a significant amount
565 of running time to be spent in process-termination checking.
566 */
567 poll_for_sigchld_id =
568 event_stream_generate_wakeup (NORMAL_SIGCHLD_CHECK_TIMEOUT_MSECS,
569 NORMAL_SIGCHLD_CHECK_TIMEOUT_MSECS,
570 Qnil, Qnil, 1);
571 }
572
573 #endif /* not SIGCHLD */
574
575 #ifdef SIGIO
576
577 static void
578 input_available_signal (int signo)
579 {
580 something_happened = 1; /* tell QUIT to wake up */
581 quit_check_signal_happened = 1;
582 quit_check_signal_tick_count++;
583 EMACS_REESTABLISH_SIGNAL (signo, input_available_signal);
584 SIGRETURN;
585 }
586
587 #endif /* SIGIO */
588
589
590 /**********************************************************************/
591 /* Enabling/disabling signals */
592 /**********************************************************************/
593
594 static int interrupts_initted;
595
596 void
597 stop_interrupts (void)
598 {
599 if (!interrupts_initted)
600 return;
601 #if defined(SIGIO) && !defined(BROKEN_SIGIO)
602 unrequest_sigio ();
603 #endif
604 stop_async_timeouts ();
605 }
606
607 void
608 start_interrupts (void)
609 {
610 if (!interrupts_initted)
611 return;
612 #if defined(SIGIO) && !defined(BROKEN_SIGIO)
613 request_sigio ();
614 #endif
615 start_async_timeouts ();
616 }
617
618 /* Cheesy but workable implementation of sleep() that doesn't
619 interfere with our periodic timers. */
620
621 void
622 emacs_sleep (int secs)
623 {
624 stop_interrupts ();
625 sleep (secs);
626 start_interrupts ();
627 }
628
629
630 /************************************************************************/
631 /* initialization */
632 /************************************************************************/
633
634 /* If we've been nohup'ed, keep it that way.
635 This allows `nohup xemacs &' to work.
636 More generally, if a normally fatal signal has been redirected
637 to SIG_IGN by our invocation environment, trust the environment.
638 This keeps xemacs from being killed by a SIGQUIT intended for a
639 different process after having been backgrounded under a
640 non-job-control shell! */
641 static void
642 handle_signal_if_fatal (int signo)
643 {
644 if (signal (signo, fatal_error_signal) == SIG_IGN)
645 signal (signo, SIG_IGN);
646 }
647
648 void
649 init_signals_very_early (void)
650 {
651 /* Catch all signals that would kill us.
652 Don't catch these signals in batch mode if not initialized.
653 On some machines, this sets static data that would make
654 signal fail to work right when the dumped Emacs is run. */
655 if (noninteractive && !initialized)
656 return;
657
658 handle_signal_if_fatal (SIGILL); /* ANSI */
659 handle_signal_if_fatal (SIGABRT); /* ANSI */
660 handle_signal_if_fatal (SIGFPE); /* ANSI */
661 handle_signal_if_fatal (SIGSEGV); /* ANSI */
662 handle_signal_if_fatal (SIGTERM); /* ANSI */
663
664
665 #ifdef SIGHUP
666 handle_signal_if_fatal (SIGHUP); /* POSIX */
667 #endif
668 #ifdef SIGQUIT
669 handle_signal_if_fatal (SIGQUIT); /* POSIX */
670 #endif
671 #ifdef SIGTRAP
672 handle_signal_if_fatal (SIGTRAP); /* POSIX */
673 #endif
674 #ifdef SIGUSR1
675 handle_signal_if_fatal (SIGUSR1); /* POSIX */
676 #endif
677 #ifdef SIGUSR2
678 handle_signal_if_fatal (SIGUSR2); /* POSIX */
679 #endif
680 #ifdef SIGPIPE
681 handle_signal_if_fatal (SIGPIPE); /* POSIX */
682 #endif
683 #ifdef SIGALRM
684 /* This will get reset later, once we're
685 capable of handling it properly. */
686 handle_signal_if_fatal (SIGALRM); /* POSIX */
687 #endif
688
689
690 #ifdef SIGBUS
691 handle_signal_if_fatal (SIGBUS); /* XPG5 */
692 #endif
693 #ifdef SIGSYS
694 handle_signal_if_fatal (SIGSYS); /* XPG5 */
695 #endif
696 #ifdef SIGXCPU
697 handle_signal_if_fatal (SIGXCPU); /* XPG5 */
698 #endif
699 #ifdef SIGXFSZ
700 handle_signal_if_fatal (SIGXFSZ); /* XPG5 */
701 #endif
702 #ifdef SIGVTALRM
703 handle_signal_if_fatal (SIGVTALRM); /* XPG5 */
704 #endif
705 #ifdef SIGPROF
706 /* Messes up the REAL profiler */
707 /* handle_signal_if_fatal (SIGPROF); */ /* XPG5 */
708 #endif
709
710
711 #ifdef SIGHWE
712 handle_signal_if_fatal (SIGHWE);
713 #endif
714 #ifdef SIGPRE
715 handle_signal_if_fatal (SIGPRE);
716 #endif
717 #ifdef SIGORE
718 handle_signal_if_fatal (SIGORE);
719 #endif
720 #ifdef SIGUME
721 handle_signal_if_fatal (SIGUME);
722 #endif
723 #ifdef SIGDLK
724 handle_signal_if_fatal (SIGDLK);
725 #endif
726 #ifdef SIGCPULIM
727 handle_signal_if_fatal (SIGCPULIM);
728 #endif
729 #ifdef SIGIOT
730 handle_signal_if_fatal (SIGIOT);
731 #endif
732 #ifdef SIGEMT
733 handle_signal_if_fatal (SIGEMT);
734 #endif
735 #ifdef SIGLOST
736 handle_signal_if_fatal (SIGLOST);
737 #endif
738 #ifdef SIGSTKFLT /* coprocessor stack fault under Linux */
739 handle_signal_if_fatal (SIGSTKFLT);
740 #endif
741 #ifdef SIGUNUSED /* exists under Linux, and will kill process! */
742 handle_signal_if_fatal (SIGUNUSED);
743 #endif
744
745 #ifdef AIX
746 /* 20 is SIGCHLD, 21 is SIGTTIN, 22 is SIGTTOU. */
747 #ifndef _I386
748 handle_signal_if_fatal (SIGIOINT);
749 #endif
750 handle_signal_if_fatal (SIGGRANT);
751 handle_signal_if_fatal (SIGRETRACT);
752 handle_signal_if_fatal (SIGSOUND);
753 handle_signal_if_fatal (SIGMSG);
754 #endif /* AIX */
755
756 #ifdef SIGDANGER
757 /* This just means available memory is getting low. */
758 signal (SIGDANGER, memory_warning_signal);
759 #endif
760 }
761
762 void
763 syms_of_signal (void)
764 {
765 DEFSUBR (Fwaiting_for_user_input_p);
766 }
767
768 void
769 init_interrupts_late (void)
770 {
771 if (!noninteractive)
772 {
773 signal (SIGINT, interrupt_signal);
774 #ifdef HAVE_TERMIO
775 /* On systems with TERMIO, C-g is set up for both SIGINT and SIGQUIT
776 and we can't tell which one it will give us. */
777 signal (SIGQUIT, interrupt_signal);
778 #endif /* HAVE_TERMIO */
779 init_async_timeouts ();
780 #ifdef SIGIO
781 signal (SIGIO, input_available_signal);
782 # ifdef SIGPOLL /* XPG5 */
783 /* Some systems (e.g. Motorola SVR4) losingly have different
784 values for SIGIO and SIGPOLL, and send SIGPOLL instead of
785 SIGIO. On those same systems, an uncaught SIGPOLL kills the
786 process. */
787 signal (SIGPOLL, input_available_signal);
788 # endif
789 #elif !defined (DONT_POLL_FOR_QUIT)
790 init_poll_for_quit ();
791 #endif
792 }
793
794 #if defined(HAVE_UNIX_PROCESSES) && !defined(SIGCHLD)
795 init_poll_for_sigchld ();
796 #endif
797
798 EMACS_UNBLOCK_ALL_SIGNALS ();
799
800 interrupts_initted = 1;
801 }
802