(U-00024532): Use `->denotational' and `->subsumptive'.
[chise/xemacs-chise.git-] / 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   qxe_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
331 unsigned int
332 alarm (unsigned int howlong)
333 {
334   struct itimerval old_it, new_it;
335
336   /* If alarm() gets called when polling isn't disabled, it can mess
337      up the periodic timer. */
338   assert (async_timer_suppress_count > 0);
339
340   new_it.it_value.tv_sec = howlong;
341   new_it.it_value.tv_usec = 0;
342   new_it.it_interval.tv_sec = 0;
343   new_it.it_interval.tv_usec = 0;
344   qxe_setitimer (ITIMER_REAL, &new_it, &old_it);
345
346   /* Never return zero if there was a timer outstanding. */
347   return old_it.it_value.tv_sec + (old_it.it_value.tv_usec > 0 ? 1 : 0);
348 }
349
350 int
351 qxe_setitimer (int kind, const struct itimerval *itnew,
352                struct itimerval *itold)
353 {
354 #if defined (WIN32_NATIVE) || defined (CYGWIN)
355   /* setitimer() does not exist on native MS Windows, and appears broken
356      on Cygwin.  See win32.c. */
357   return mswindows_setitimer (kind, itnew, itold);
358 #else
359   return setitimer (kind, itnew, itold);
360 #endif
361 }
362
363 #endif /* HAVE_SETITIMER */
364
365
366 DEFUN ("waiting-for-user-input-p", Fwaiting_for_user_input_p, 0, 0, 0, /*
367 Return non-nil if XEmacs is waiting for input from the user.
368 This is intended for use by asynchronous timeout callbacks and by
369 asynchronous process output filters and sentinels (not yet implemented
370 in XEmacs).  It will always be nil if XEmacs is not inside of
371 an asynchronous timeout or process callback.
372 */
373        ())
374 {
375   return waiting_for_user_input_p ? Qt : Qnil;
376 }
377
378 \f
379 /**********************************************************************/
380 /*                        Control-G checking                          */
381 /**********************************************************************/
382
383 /* Set this for debugging, to have a way to get out */
384 int stop_character; /* #### not currently implemented */
385
386 /* This routine is called in response to a SIGINT or SIGQUIT.
387    On TTY's, one of these two signals will get generated in response
388    to C-g.  (When running under X, C-g is handled using the SIGIO
389    handler, which sets a flag telling the QUIT macro to scan the
390    unread events for a ^G.)
391
392    Otherwise it sets the Lisp variable  quit-flag  not-nil.
393    This causes  eval  to throw, when it gets a chance.
394    If  quit-flag  is already non-nil, it stops the job right away.  */
395
396 static SIGTYPE
397 interrupt_signal (int sig)
398 {
399   /* This function can call lisp */
400   /* #### we should NOT be calling lisp from a signal handler, boys
401      and girls */
402   /* Must preserve main program's value of errno.  */
403   int old_errno = errno;
404
405   EMACS_REESTABLISH_SIGNAL (sig, interrupt_signal);
406
407 /* with the macroized error-checking stuff, the garbage below
408    may mess things up because XCONSOLE() and such can use and
409    change global vars. */
410 #if ! (defined (ERROR_CHECK_TYPECHECK) && defined (MACROIZE_ERROR_CHECKING))
411   if (sigint_happened && CONSOLEP (Vcontrolling_terminal) &&
412       CONSOLE_LIVE_P (XCONSOLE (Vcontrolling_terminal)) &&
413       !emacs_is_blocking)
414     {
415       char c;
416       fflush (stdout);
417       reset_initial_console ();
418       EMACS_UNBLOCK_SIGNAL (sig);
419 #ifdef SIGTSTP                  /* Support possible in later USG versions */
420 /*
421  * On systems which can suspend the current process and return to the original
422  * shell, this command causes the user to end up back at the shell.
423  * The "Auto-save" and "Abort" questions are not asked until
424  * the user elects to return to emacs, at which point he can save the current
425  * job and either dump core or continue.
426  */
427       sys_suspend ();
428 #else
429       /* Perhaps should really fork an inferior shell?
430          But that would not provide any way to get back
431          to the original shell, ever.  */
432       stdout_out ("No support for stopping a process on this operating system;\n");
433       stdout_out ("you can continue or abort.\n");
434 #endif /* not SIGTSTP */
435       stdout_out ("Auto-save? (y or n) ");
436       if (((c = getc (stdin)) & ~040) == 'Y')
437         Fdo_auto_save (Qnil, Qnil);
438       while (c != '\n')
439         c = getc (stdin);
440       stdout_out ("Abort (and dump core)? (y or n) ");
441       if (((c = getc (stdin)) & ~040) == 'Y')
442         ABORT ();
443       while (c != '\n')
444         c = getc (stdin);
445       stdout_out ("Continuing...\n");
446       reinit_initial_console ();
447       MARK_FRAME_CHANGED (XFRAME (DEVICE_SELECTED_FRAME
448                                   (XDEVICE (CONSOLE_SELECTED_DEVICE
449                                             (XCONSOLE
450                                              (Vcontrolling_terminal))))));
451     }
452   else
453 #endif /* ! (defined (ERROR_CHECKING) && defined (MACROIZE_ERROR_CHECKING)) */
454     {
455       /* Else request quit when it's safe */
456       Vquit_flag = Qt;
457       sigint_happened = 1;
458 #ifdef HAVE_UNIXOID_EVENT_LOOP
459       signal_fake_event ();
460 #endif
461     }
462   errno = old_errno;
463   SIGRETURN;
464 }
465
466 static Lisp_Object
467 restore_dont_check_for_quit (Lisp_Object val)
468 {
469   dont_check_for_quit = XINT (val);
470   return Qnil;
471 }
472
473 void
474 begin_dont_check_for_quit (void)
475 {
476   specbind (Qinhibit_quit, Qt);
477   record_unwind_protect (restore_dont_check_for_quit,
478                          make_int (dont_check_for_quit));
479   dont_check_for_quit = 1;
480 }
481
482 /* The effect of this function is to set Vquit_flag if the user pressed
483    ^G and discard the ^G, so as to not notice the same ^G again. */
484 int
485 check_quit (void)
486 {
487   /* dont_check_for_quit is set in two circumstances:
488
489      (1) when we are in the process of changing the window
490      configuration.  The frame might be in an inconsistent state,
491      which will cause assertion failures if we check for QUIT.
492
493      (2) when we are reading events, and want to read the C-g
494      as an event.  The normal check for quit will discard the C-g,
495      which would be bad.
496
497      #### C-g is still often read as quit, e.g. if you type C-x C-g
498      (the C-g happens during the sit-for in maybe_echo_keys(); even
499      if we attempt to inhibit quit here, there is still a check
500      later on for QUIT.  To fix this properly requires a fairly
501      substantial overhaul of the quit-checking code, which is
502      probably not worth it.)
503
504      We should *not* conditionalize on Vinhibit_quit, or
505      critical-quit (Control-Shift-G) won't work right. */
506
507   if (dont_check_for_quit)
508     return 0;
509
510   if (quit_check_signal_happened)
511     {
512       quit_check_signal_happened = 0;
513       event_stream_quit_p ();
514       return 1;
515     }
516   else
517     return 0;
518 }
519
520 int
521 check_what_happened (void)              /* called from QUIT when
522                                            something_happened gets set */
523 {
524   something_happened = 0;
525   if (alarm_happened)
526     {
527       alarm_happened = 0;
528       handle_alarm_going_off ();
529     }
530   return check_quit ();
531 }
532
533 \f
534
535 void
536 init_poll_for_quit (void)
537 {
538 #if !defined (SIGIO) && !defined (DONT_POLL_FOR_QUIT)
539   /* Check for C-g every 1/4 of a second.
540
541      #### This is just a guess.  Some investigation will have to be
542      done to see what the best value is.  The best value is the
543      smallest possible value that doesn't cause a significant amount
544      of running time to be spent in C-g checking. */
545   if (!poll_for_quit_id)
546     poll_for_quit_id =
547       event_stream_generate_wakeup (NORMAL_QUIT_CHECK_TIMEOUT_MSECS,
548                                     NORMAL_QUIT_CHECK_TIMEOUT_MSECS,
549                                     Qnil, Qnil, 1);
550 #endif /* not SIGIO and not DONT_POLL_FOR_QUIT */
551 }
552
553 void
554 reset_poll_for_quit (void)
555 {
556 #if !defined (SIGIO) && !defined (DONT_POLL_FOR_QUIT)
557   if (poll_for_quit_id)
558     {
559       event_stream_disable_wakeup (poll_for_quit_id, 1);
560       poll_for_quit_id = 0;
561     }
562 #endif /* not SIGIO and not DONT_POLL_FOR_QUIT */
563 }
564
565 #if defined(HAVE_UNIX_PROCESSES) && !defined(SIGCHLD)
566
567 static void
568 init_poll_for_sigchld (void)
569 {
570   /* Check for terminated processes every 1/4 of a second.
571
572      #### This is just a guess.  Some investigation will have to be
573      done to see what the best value is.  The best value is the
574      smallest possible value that doesn't cause a significant amount
575      of running time to be spent in process-termination checking.
576      */
577   poll_for_sigchld_id =
578     event_stream_generate_wakeup (NORMAL_SIGCHLD_CHECK_TIMEOUT_MSECS,
579                                   NORMAL_SIGCHLD_CHECK_TIMEOUT_MSECS,
580                                   Qnil, Qnil, 1);
581 }
582
583 #endif /* not SIGCHLD */
584
585 #ifdef SIGIO
586
587 static void
588 input_available_signal (int signo)
589 {
590   something_happened = 1; /* tell QUIT to wake up */
591   quit_check_signal_happened = 1;
592   quit_check_signal_tick_count++;
593   EMACS_REESTABLISH_SIGNAL (signo, input_available_signal);
594   SIGRETURN;
595 }
596
597 #endif /* SIGIO */
598
599 \f
600 /**********************************************************************/
601 /*                     Enabling/disabling signals                     */
602 /**********************************************************************/
603
604 static int interrupts_initted;
605
606 void
607 stop_interrupts (void)
608 {
609   if (!interrupts_initted)
610     return;
611 #if defined(SIGIO) && !defined(BROKEN_SIGIO)
612   unrequest_sigio ();
613 #endif
614   stop_async_timeouts ();
615 }
616
617 void
618 start_interrupts (void)
619 {
620   if (!interrupts_initted)
621     return;
622 #if defined(SIGIO) && !defined(BROKEN_SIGIO)
623   request_sigio ();
624 #endif
625   start_async_timeouts ();
626 }
627
628 /* Cheesy but workable implementation of sleep() that doesn't
629    interfere with our periodic timers. */
630
631 void
632 emacs_sleep (int secs)
633 {
634   stop_interrupts ();
635   sleep (secs);
636   start_interrupts ();
637 }
638
639 \f
640 /************************************************************************/
641 /*                            initialization                            */
642 /************************************************************************/
643
644 /* If we've been nohup'ed, keep it that way.
645    This allows `nohup xemacs &' to work.
646    More generally, if a normally fatal signal has been redirected
647    to SIG_IGN by our invocation environment, trust the environment.
648    This keeps xemacs from being killed by a SIGQUIT intended for a
649    different process after having been backgrounded under a
650    non-job-control shell! */
651 static void
652 handle_signal_if_fatal (int signo)
653 {
654   if (signal (signo,  fatal_error_signal) == SIG_IGN)
655     signal (signo, SIG_IGN);
656 }
657
658 void
659 init_signals_very_early (void)
660 {
661   /* Catch all signals that would kill us.
662      Don't catch these signals in batch mode if not initialized.
663      On some machines, this sets static data that would make
664      signal fail to work right when the dumped Emacs is run.  */
665   if (noninteractive && !initialized)
666     return;
667
668   handle_signal_if_fatal (SIGILL);  /* ANSI */
669   handle_signal_if_fatal (SIGABRT); /* ANSI */
670   handle_signal_if_fatal (SIGFPE);  /* ANSI */
671   handle_signal_if_fatal (SIGSEGV); /* ANSI */
672   handle_signal_if_fatal (SIGTERM); /* ANSI */
673
674
675 #ifdef SIGHUP
676   handle_signal_if_fatal (SIGHUP);  /* POSIX */
677 #endif
678 #ifdef SIGQUIT
679   handle_signal_if_fatal (SIGQUIT); /* POSIX */
680 #endif
681 #ifdef SIGTRAP
682   handle_signal_if_fatal (SIGTRAP); /* POSIX */
683 #endif
684 #ifdef SIGUSR1
685   handle_signal_if_fatal (SIGUSR1); /* POSIX */
686 #endif
687 #ifdef SIGUSR2
688   handle_signal_if_fatal (SIGUSR2); /* POSIX */
689 #endif
690 #ifdef SIGPIPE
691   handle_signal_if_fatal (SIGPIPE); /* POSIX */
692 #endif
693 #ifdef SIGALRM
694   /* This will get reset later, once we're
695      capable of handling it properly. */
696   handle_signal_if_fatal (SIGALRM); /* POSIX */
697 #endif
698
699
700 #ifdef SIGBUS
701   handle_signal_if_fatal (SIGBUS);  /* XPG5 */
702 #endif
703 #ifdef SIGSYS
704   handle_signal_if_fatal (SIGSYS);  /* XPG5 */
705 #endif
706 #ifdef SIGXCPU
707   handle_signal_if_fatal (SIGXCPU); /* XPG5 */
708 #endif
709 #ifdef SIGXFSZ
710   handle_signal_if_fatal (SIGXFSZ); /* XPG5 */
711 #endif
712 #ifdef SIGVTALRM
713   handle_signal_if_fatal (SIGVTALRM); /* XPG5 */
714 #endif
715 #ifdef SIGPROF
716   /* Messes up the REAL profiler */
717   /* handle_signal_if_fatal (SIGPROF); */ /* XPG5 */
718 #endif
719
720
721 #ifdef SIGHWE
722   handle_signal_if_fatal (SIGHWE);
723 #endif
724 #ifdef SIGPRE
725   handle_signal_if_fatal (SIGPRE);
726 #endif
727 #ifdef SIGORE
728   handle_signal_if_fatal (SIGORE);
729 #endif
730 #ifdef SIGUME
731   handle_signal_if_fatal (SIGUME);
732 #endif
733 #ifdef SIGDLK
734   handle_signal_if_fatal (SIGDLK);
735 #endif
736 #ifdef SIGCPULIM
737   handle_signal_if_fatal (SIGCPULIM);
738 #endif
739 #ifdef SIGIOT
740   handle_signal_if_fatal (SIGIOT);
741 #endif
742 #ifdef SIGEMT
743   handle_signal_if_fatal (SIGEMT);
744 #endif
745 #ifdef SIGLOST
746   handle_signal_if_fatal (SIGLOST);
747 #endif
748 #ifdef SIGSTKFLT /* coprocessor stack fault under Linux */
749   handle_signal_if_fatal (SIGSTKFLT);
750 #endif
751 #ifdef SIGUNUSED /* exists under Linux, and will kill process! */
752   handle_signal_if_fatal (SIGUNUSED);
753 #endif
754
755 #ifdef AIX
756 /* 20 is SIGCHLD, 21 is SIGTTIN, 22 is SIGTTOU.  */
757 #ifndef _I386
758   handle_signal_if_fatal (SIGIOINT);
759 #endif
760   handle_signal_if_fatal (SIGGRANT);
761   handle_signal_if_fatal (SIGRETRACT);
762   handle_signal_if_fatal (SIGSOUND);
763   handle_signal_if_fatal (SIGMSG);
764 #endif /* AIX */
765
766 #ifdef SIGDANGER
767   /* This just means available memory is getting low.  */
768   signal (SIGDANGER, memory_warning_signal);
769 #endif
770 }
771
772 void
773 syms_of_signal (void)
774 {
775   DEFSUBR (Fwaiting_for_user_input_p);
776 }
777
778 void
779 init_interrupts_late (void)
780 {
781   if (!noninteractive)
782     {
783       signal (SIGINT, interrupt_signal);
784 #ifdef HAVE_TERMIO
785       /* On  systems with TERMIO, C-g is set up for both SIGINT and SIGQUIT
786          and we can't tell which one it will give us.  */
787       signal (SIGQUIT, interrupt_signal);
788 #endif /* HAVE_TERMIO */
789       init_async_timeouts ();
790 #ifdef SIGIO
791       signal (SIGIO, input_available_signal);
792 # ifdef SIGPOLL /* XPG5 */
793       /* Some systems (e.g. Motorola SVR4) losingly have different
794          values for SIGIO and SIGPOLL, and send SIGPOLL instead of
795          SIGIO.  On those same systems, an uncaught SIGPOLL kills the
796          process. */
797       signal (SIGPOLL, input_available_signal);
798 # endif
799 #elif !defined (DONT_POLL_FOR_QUIT)
800       init_poll_for_quit ();
801 #endif
802     }
803
804 #if defined(HAVE_UNIX_PROCESSES) && !defined(SIGCHLD)
805   init_poll_for_sigchld ();
806 #endif
807
808   EMACS_UNBLOCK_ALL_SIGNALS ();
809
810   interrupts_initted = 1;
811 }
812