XEmacs 21.2.32 "Kastor & Polydeukes".
[chise/xemacs-chise.git.1] / src / signal.c
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 \f
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 \f
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       if (((c = getc (stdin)) & ~040) == 'Y')
424         Fdo_auto_save (Qnil, Qnil);
425       while (c != '\n')
426         c = getc (stdin);
427       stdout_out ("Abort (and dump core)? (y or n) ");
428       if (((c = getc (stdin)) & ~040) == 'Y')
429         abort ();
430       while (c != '\n')
431         c = getc (stdin);
432       stdout_out ("Continuing...\n");
433       reinit_initial_console ();
434       MARK_FRAME_CHANGED (XFRAME (DEVICE_SELECTED_FRAME
435                                   (XDEVICE (CONSOLE_SELECTED_DEVICE
436                                             (XCONSOLE
437                                              (Vcontrolling_terminal))))));
438     }
439   else
440 #endif /* ! (defined (ERROR_CHECKING) && defined (MACROIZE_ERROR_CHECKING)) */
441     {
442       /* Else request quit when it's safe */
443       Vquit_flag = Qt;
444       sigint_happened = 1;
445 #ifdef HAVE_UNIXOID_EVENT_LOOP
446       signal_fake_event ();
447 #endif
448     }
449   errno = old_errno;
450   SIGRETURN;
451 }
452
453 static Lisp_Object
454 restore_dont_check_for_quit (Lisp_Object val)
455 {
456   dont_check_for_quit = XINT (val);
457   return Qnil;
458 }
459
460 void
461 begin_dont_check_for_quit (void)
462 {
463   specbind (Qinhibit_quit, Qt);
464   record_unwind_protect (restore_dont_check_for_quit,
465                          make_int (dont_check_for_quit));
466   dont_check_for_quit = 1;
467 }
468
469 /* The effect of this function is to set Vquit_flag if the user pressed
470    ^G and discard the ^G, so as to not notice the same ^G again. */
471 int
472 check_quit (void)
473 {
474   /* dont_check_for_quit is set in two circumstances:
475
476      (1) when we are in the process of changing the window
477      configuration.  The frame might be in an inconsistent state,
478      which will cause assertion failures if we check for QUIT.
479
480      (2) when we are reading events, and want to read the C-g
481      as an event.  The normal check for quit will discard the C-g,
482      which would be bad.
483
484      #### C-g is still often read as quit, e.g. if you type C-x C-g
485      (the C-g happens during the sit-for in maybe_echo_keys(); even
486      if we attempt to inhibit quit here, there is still a check
487      later on for QUIT.  To fix this properly requires a fairly
488      substantial overhaul of the quit-checking code, which is
489      probably not worth it.)
490
491      We should *not* conditionalize on Vinhibit_quit, or
492      critical-quit (Control-Shift-G) won't work right. */
493
494   if (dont_check_for_quit)
495     return 0;
496
497   if (quit_check_signal_happened)
498     {
499       quit_check_signal_happened = 0;
500       event_stream_quit_p ();
501       return 1;
502     }
503   else
504     return 0;
505 }
506
507 int
508 check_what_happened (void)              /* called from QUIT when
509                                            something_happened gets set */
510 {
511   something_happened = 0;
512   if (alarm_happened)
513     {
514       alarm_happened = 0;
515       handle_alarm_going_off ();
516     }
517   return check_quit ();
518 }
519
520 \f
521
522 void
523 init_poll_for_quit (void)
524 {
525 #if !defined (SIGIO) && !defined (DONT_POLL_FOR_QUIT)
526   /* Check for C-g every 1/4 of a second.
527
528      #### This is just a guess.  Some investigation will have to be
529      done to see what the best value is.  The best value is the
530      smallest possible value that doesn't cause a significant amount
531      of running time to be spent in C-g checking. */
532   if (!poll_for_quit_id)
533     poll_for_quit_id =
534       event_stream_generate_wakeup (NORMAL_QUIT_CHECK_TIMEOUT_MSECS,
535                                     NORMAL_QUIT_CHECK_TIMEOUT_MSECS,
536                                     Qnil, Qnil, 1);
537 #endif /* not SIGIO and not DONT_POLL_FOR_QUIT */
538 }
539
540 void
541 reset_poll_for_quit (void)
542 {
543 #if !defined (SIGIO) && !defined (DONT_POLL_FOR_QUIT)
544   if (poll_for_quit_id)
545     {
546       event_stream_disable_wakeup (poll_for_quit_id, 1);
547       poll_for_quit_id = 0;
548     }
549 #endif /* not SIGIO and not DONT_POLL_FOR_QUIT */
550 }
551
552 #if defined(HAVE_UNIX_PROCESSES) && !defined(SIGCHLD)
553
554 static void
555 init_poll_for_sigchld (void)
556 {
557   /* Check for terminated processes every 1/4 of a second.
558
559      #### This is just a guess.  Some investigation will have to be
560      done to see what the best value is.  The best value is the
561      smallest possible value that doesn't cause a significant amount
562      of running time to be spent in process-termination checking.
563      */
564   poll_for_sigchld_id =
565     event_stream_generate_wakeup (NORMAL_SIGCHLD_CHECK_TIMEOUT_MSECS,
566                                   NORMAL_SIGCHLD_CHECK_TIMEOUT_MSECS,
567                                   Qnil, Qnil, 1);
568 }
569
570 #endif /* not SIGCHLD */
571
572 #ifdef SIGIO
573
574 static void
575 input_available_signal (int signo)
576 {
577   something_happened = 1; /* tell QUIT to wake up */
578   quit_check_signal_happened = 1;
579   quit_check_signal_tick_count++;
580   EMACS_REESTABLISH_SIGNAL (signo, input_available_signal);
581   SIGRETURN;
582 }
583
584 #endif /* SIGIO */
585
586 \f
587 /**********************************************************************/
588 /*                     Enabling/disabling signals                     */
589 /**********************************************************************/
590
591 static int interrupts_initted;
592
593 void
594 stop_interrupts (void)
595 {
596   if (!interrupts_initted)
597     return;
598 #if defined(SIGIO) && !defined(BROKEN_SIGIO)
599   unrequest_sigio ();
600 #endif
601   stop_async_timeouts ();
602 }
603
604 void
605 start_interrupts (void)
606 {
607   if (!interrupts_initted)
608     return;
609 #if defined(SIGIO) && !defined(BROKEN_SIGIO)
610   request_sigio ();
611 #endif
612   start_async_timeouts ();
613 }
614
615 /* Cheesy but workable implementation of sleep() that doesn't
616    interfere with our periodic timers. */
617
618 void
619 emacs_sleep (int secs)
620 {
621   stop_interrupts ();
622   sleep (secs);
623   start_interrupts ();
624 }
625
626 \f
627 /************************************************************************/
628 /*                            initialization                            */
629 /************************************************************************/
630
631 /* If we've been nohup'ed, keep it that way.
632    This allows `nohup xemacs &' to work.
633    More generally, if a normally fatal signal has been redirected
634    to SIG_IGN by our invocation environment, trust the environment.
635    This keeps xemacs from being killed by a SIGQUIT intended for a
636    different process after having been backgrounded under a
637    non-job-control shell! */
638 static void
639 handle_signal_if_fatal (int signo)
640 {
641   if (signal (signo,  fatal_error_signal) == SIG_IGN)
642     signal (signo, SIG_IGN);
643 }
644
645 void
646 init_signals_very_early (void)
647 {
648   /* Catch all signals that would kill us.
649      Don't catch these signals in batch mode if not initialized.
650      On some machines, this sets static data that would make
651      signal fail to work right when the dumped Emacs is run.  */
652   if (noninteractive && !initialized)
653     return;
654
655   handle_signal_if_fatal (SIGILL);  /* ANSI */
656   handle_signal_if_fatal (SIGABRT); /* ANSI */
657   handle_signal_if_fatal (SIGFPE);  /* ANSI */
658   handle_signal_if_fatal (SIGSEGV); /* ANSI */
659   handle_signal_if_fatal (SIGTERM); /* ANSI */
660
661
662 #ifdef SIGHUP
663   handle_signal_if_fatal (SIGHUP);  /* POSIX */
664 #endif
665 #ifdef SIGQUIT
666   handle_signal_if_fatal (SIGQUIT); /* POSIX */
667 #endif
668 #ifdef SIGTRAP
669   handle_signal_if_fatal (SIGTRAP); /* POSIX */
670 #endif
671 #ifdef SIGUSR1
672   handle_signal_if_fatal (SIGUSR1); /* POSIX */
673 #endif
674 #ifdef SIGUSR2
675   handle_signal_if_fatal (SIGUSR2); /* POSIX */
676 #endif
677 #ifdef SIGPIPE
678   handle_signal_if_fatal (SIGPIPE); /* POSIX */
679 #endif
680 #ifdef SIGALRM
681   /* This will get reset later, once we're
682      capable of handling it properly. */
683   handle_signal_if_fatal (SIGALRM); /* POSIX */
684 #endif
685
686
687 #ifdef SIGBUS
688   handle_signal_if_fatal (SIGBUS);  /* XPG5 */
689 #endif
690 #ifdef SIGSYS
691   handle_signal_if_fatal (SIGSYS);  /* XPG5 */
692 #endif
693 #ifdef SIGXCPU
694   handle_signal_if_fatal (SIGXCPU); /* XPG5 */
695 #endif
696 #ifdef SIGXFSZ
697   handle_signal_if_fatal (SIGXFSZ); /* XPG5 */
698 #endif
699 #ifdef SIGVTALRM
700   handle_signal_if_fatal (SIGVTALRM); /* XPG5 */
701 #endif
702 #ifdef SIGPROF
703   /* Messes up the REAL profiler */
704   /* handle_signal_if_fatal (SIGPROF); */ /* XPG5 */
705 #endif
706
707
708 #ifdef SIGHWE
709   handle_signal_if_fatal (SIGHWE);
710 #endif
711 #ifdef SIGPRE
712   handle_signal_if_fatal (SIGPRE);
713 #endif
714 #ifdef SIGORE
715   handle_signal_if_fatal (SIGORE);
716 #endif
717 #ifdef SIGUME
718   handle_signal_if_fatal (SIGUME);
719 #endif
720 #ifdef SIGDLK
721   handle_signal_if_fatal (SIGDLK);
722 #endif
723 #ifdef SIGCPULIM
724   handle_signal_if_fatal (SIGCPULIM);
725 #endif
726 #ifdef SIGIOT
727   handle_signal_if_fatal (SIGIOT);
728 #endif
729 #ifdef SIGEMT
730   handle_signal_if_fatal (SIGEMT);
731 #endif
732 #ifdef SIGLOST
733   handle_signal_if_fatal (SIGLOST);
734 #endif
735 #ifdef SIGSTKFLT /* coprocessor stack fault under Linux */
736   handle_signal_if_fatal (SIGSTKFLT);
737 #endif
738 #ifdef SIGUNUSED /* exists under Linux, and will kill process! */
739   handle_signal_if_fatal (SIGUNUSED);
740 #endif
741
742 #ifdef AIX
743 /* 20 is SIGCHLD, 21 is SIGTTIN, 22 is SIGTTOU.  */
744 #ifndef _I386
745   handle_signal_if_fatal (SIGIOINT);
746 #endif
747   handle_signal_if_fatal (SIGGRANT);
748   handle_signal_if_fatal (SIGRETRACT);
749   handle_signal_if_fatal (SIGSOUND);
750   handle_signal_if_fatal (SIGMSG);
751 #endif /* AIX */
752
753 #ifdef SIGDANGER
754   /* This just means available memory is getting low.  */
755   signal (SIGDANGER, memory_warning_signal);
756 #endif
757 }
758
759 void
760 syms_of_signal (void)
761 {
762   DEFSUBR (Fwaiting_for_user_input_p);
763 }
764
765 void
766 init_interrupts_late (void)
767 {
768   if (!noninteractive)
769     {
770       signal (SIGINT, interrupt_signal);
771 #ifdef HAVE_TERMIO
772       /* On  systems with TERMIO, C-g is set up for both SIGINT and SIGQUIT
773          and we can't tell which one it will give us.  */
774       signal (SIGQUIT, interrupt_signal);
775 #endif /* HAVE_TERMIO */
776       init_async_timeouts ();
777 #ifdef SIGIO
778       signal (SIGIO, input_available_signal);
779 # ifdef SIGPOLL /* XPG5 */
780       /* Some systems (e.g. Motorola SVR4) losingly have different
781          values for SIGIO and SIGPOLL, and send SIGPOLL instead of
782          SIGIO.  On those same systems, an uncaught SIGPOLL kills the
783          process. */
784       signal (SIGPOLL, input_available_signal);
785 # endif
786 #elif !defined (DONT_POLL_FOR_QUIT)
787       init_poll_for_quit ();
788 #endif
789     }
790
791 #if defined(HAVE_UNIX_PROCESSES) && !defined(SIGCHLD)
792   init_poll_for_sigchld ();
793 #endif
794
795   EMACS_UNBLOCK_ALL_SIGNALS ();
796
797   interrupts_initted = 1;
798 }
799