XEmacs 21.2.5
[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       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 \f
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 \f
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 \f
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