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