--- /dev/null
+/* Handling asynchronous signals.
+ Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
+ Copyright (C) 1995, 1996 Ben Wing.
+
+This file is part of XEmacs.
+
+XEmacs is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 2, or (at your option) any
+later version.
+
+XEmacs is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with XEmacs; see the file COPYING. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
+
+/* Synched up with: Not synched with FSF. Split out of keyboard.c. */
+
+#include <config.h>
+#include "lisp.h"
+
+#include "console.h"
+#include "events.h" /* for signal_fake_event() */
+#include "frame.h"
+#include "sysdep.h"
+#include "syssignal.h"
+#include "systime.h"
+
+#include "sysfile.h"
+
+/* Set to 1 when a quit-check signal (either a SIGIO interrupt or
+ the asynch. timeout for poll-for-quit) occurs. The QUITP
+ macro may look at this. */
+volatile int quit_check_signal_happened;
+
+/* Count of the number of times a quit-check signal has occurred.
+ Some stuff in event-Xt.c looks at this. */
+volatile int quit_check_signal_tick_count;
+
+/* Set to 1 when a SIGINT (or SIGQUIT) interrupt is processed.
+ maybe_read_quit_event() looks at this. */
+volatile int sigint_happened;
+
+/* Set to 1 when an asynch. timeout signal occurs. */
+static volatile int alarm_happened;
+
+/* This is used to synchronize setting the waiting_for_user_input_p
+ flag. */
+static volatile int alarm_happened_while_emacs_was_blocking;
+
+/* See check_quit() for when this is set. */
+int dont_check_for_quit;
+
+#if !defined (SIGIO) && !defined (DONT_POLL_FOR_QUIT)
+int poll_for_quit_id;
+#endif
+
+#if defined(HAVE_UNIX_PROCESSES) && !defined(SIGCHLD)
+int poll_for_sigchld_id;
+#endif
+
+/* This variable is used to communicate to a lisp
+ process-filter/sentinel/asynchronous callback (via the function
+ Fwaiting_for_user_input_p below) whether XEmacs was waiting for
+ user-input when that process-filter was called. */
+static int waiting_for_user_input_p;
+
+static int interrupts_slowed_down;
+
+#define SLOWED_DOWN_INTERRUPTS_SECS 15
+#define NORMAL_QUIT_CHECK_TIMEOUT_MSECS 250
+#define NORMAL_SIGCHLD_CHECK_TIMEOUT_MSECS 250
+
+/* Used so that signals can break out of system calls that aren't
+ naturally interruptible. */
+
+JMP_BUF break_system_call_jump;
+volatile int can_break_system_calls;
+
+\f
+/**********************************************************************/
+/* Asynchronous timeout functions */
+/**********************************************************************/
+
+/* The pending timers are stored in an ordered list, where the first timer
+ on the list is the first one to fire. Times recorded here are
+ absolute. */
+static struct low_level_timeout *async_timer_queue;
+
+/* Nonzero means async timers are temporarily suppressed. */
+static int async_timer_suppress_count;
+
+static void
+set_one_shot_timer (EMACS_TIME interval)
+{
+#ifdef HAVE_SETITIMER
+ struct itimerval it;
+ it.it_value = interval;
+ EMACS_SET_SECS_USECS (it.it_interval, 0, 0);
+ qxe_setitimer (ITIMER_REAL, &it, 0);
+#else
+ int secs;
+ EMACS_TIME_TO_INT (interval, secs);
+ alarm (secs);
+#endif
+}
+
+static void
+reset_interval_timer (void)
+{
+ EMACS_TIME interval;
+
+ /* Get the interval to set. If an interval is available,
+ make sure it's not zero (this is a valid return, but it will
+ cause the timer to get disabled, so convert it to a very short
+ time). */
+ if (get_low_level_timeout_interval (async_timer_queue, &interval))
+ {
+ if (EMACS_SECS (interval) == 0 && EMACS_USECS (interval) == 0)
+ EMACS_SET_USECS (interval, 1);
+ }
+ else
+ /* A time of 0 means "disable". */
+ EMACS_SET_SECS_USECS (interval, 0, 0);
+
+ set_one_shot_timer (interval);
+}
+
+int
+event_stream_add_async_timeout (EMACS_TIME thyme)
+{
+ int id = add_low_level_timeout (&async_timer_queue, thyme);
+
+ /* If this timeout is at the head of the queue, then we need to
+ set the timer right now for this timeout. Otherwise, things
+ are fine as-is; after the timers ahead of us are signalled,
+ the timer will be set for us. */
+
+ if (async_timer_queue->id == id)
+ reset_interval_timer ();
+
+ return id;
+}
+
+void
+event_stream_remove_async_timeout (int id)
+{
+ int first = (async_timer_queue && async_timer_queue->id == id);
+ remove_low_level_timeout (&async_timer_queue, id);
+
+ /* If we removed the timeout from the head of the queue, then
+ we need to reset the interval timer right now. */
+ if (first)
+ reset_interval_timer ();
+}
+
+/* Handle an alarm once each second and read pending input
+ so as to handle a C-g if it comes in. */
+
+static SIGTYPE
+alarm_signal (int signo)
+{
+ if (interrupts_slowed_down)
+ {
+ something_happened = 1; /* tell QUIT to wake up */
+ /* we are in "slowed-down interrupts" mode; the only alarm
+ happening here is the slowed-down quit-check alarm, so
+ we set this flag.
+
+ Do NOT set alarm_happened, because we don't want anyone
+ looking at the timeout queue. We didn't set it and
+ it needs to stay the way it is. */
+ quit_check_signal_happened = 1;
+
+#ifdef WIN32_NATIVE
+ can_break_system_calls = 0;
+#else
+ /* can_break_system_calls is set when we want to break out of
+ non-interruptible system calls. */
+ if (can_break_system_calls)
+ {
+ /* reset the flag for safety and such. Do this *before*
+ unblocking or reestablishing the signal to avoid potential
+ race conditions. */
+ can_break_system_calls = 0;
+ EMACS_UNBLOCK_SIGNAL (signo);
+ EMACS_REESTABLISH_SIGNAL (signo, alarm_signal);
+ LONGJMP (break_system_call_jump, 0);
+ }
+#endif
+
+ EMACS_REESTABLISH_SIGNAL (signo, alarm_signal);
+ SIGRETURN;
+ }
+
+ something_happened = 1; /* tell QUIT to wake up */
+ alarm_happened = 1;
+ if (emacs_is_blocking)
+ alarm_happened_while_emacs_was_blocking = 1;
+ /* #### This is for QUITP. When it is run, it may not be the
+ place to do arbitrary stuff like run asynch. handlers, but
+ it needs to know whether the poll-for-quit asynch. timeout
+ went off. Rather than put the code in to compute this
+ specially, we just set this flag. Should fix this. */
+ quit_check_signal_happened = 1;
+
+#ifdef HAVE_UNIXOID_EVENT_LOOP
+ signal_fake_event ();
+#endif
+
+ EMACS_REESTABLISH_SIGNAL (signo, alarm_signal);
+ SIGRETURN;
+}
+
+static void
+init_async_timeouts (void)
+{
+ signal (SIGALRM, alarm_signal);
+ async_timer_suppress_count = 0;
+}
+
+/* Turn off async timeouts. */
+
+static void
+stop_async_timeouts (void)
+{
+ if (async_timer_suppress_count == 0)
+ {
+ /* If timer was on, turn it off. */
+ EMACS_TIME thyme;
+ EMACS_SET_SECS_USECS (thyme, 0, 0);
+ set_one_shot_timer (thyme);
+ }
+ async_timer_suppress_count++;
+}
+
+/* Turn on async timeouts again. */
+
+static void
+start_async_timeouts (void)
+{
+ assert (async_timer_suppress_count > 0);
+ async_timer_suppress_count--;
+ if (async_timer_suppress_count == 0)
+ {
+ /* Some callers turn off async timeouts and then use the alarm
+ for their own purposes; so reinitialize everything. */
+ signal (SIGALRM, alarm_signal);
+ reset_interval_timer ();
+ }
+}
+
+/* Some functions don't like being interrupted with SIGALRM or SIGIO.
+ Previously we were calling stop_interrupts() / start_interrupts(),
+ but then if the program hangs in one of those functions, e.g.
+ waiting for a connect(), we're really screwed. So instead we
+ just "slow them down". We do this by disabling all interrupts
+ and then installing a timer of length fairly large, like 5 or
+ 10 secs. That way, any "legitimate" connections (which should
+ take a fairly short amount of time) go through OK, but we can
+ interrupt bogus ones. */
+
+void
+slow_down_interrupts (void)
+{
+ EMACS_TIME thyme;
+
+ /* We have to set the flag *before* setting the slowed-down timer,
+ to avoid a race condition -- if the signal occurs between the
+ call to set_one_shot_timer() and the setting of this flag,
+ alarm_happened will get set, which will be a Bad Thing if
+ there were no timeouts on the queue. */
+ interrupts_slowed_down++;
+ if (interrupts_slowed_down == 1)
+ {
+ stop_interrupts ();
+ EMACS_SET_SECS_USECS (thyme, SLOWED_DOWN_INTERRUPTS_SECS, 0);
+ set_one_shot_timer (thyme);
+ }
+}
+
+void
+speed_up_interrupts (void)
+{
+ if (interrupts_slowed_down > 0)
+ {
+ start_interrupts ();
+ /* Change this flag AFTER fiddling with interrupts, for the same
+ race-condition reasons as above. */
+ interrupts_slowed_down--;
+ }
+}
+
+static void
+handle_alarm_going_off (void)
+{
+ int interval_id;
+
+ /* If asynch. timeouts are blocked, then don't do anything now,
+ but make this function get called again next QUIT.
+
+ #### This is a bit inefficient because there will be function call
+ overhead each time QUIT occurs. */
+
+ if (!NILP (Vinhibit_quit))
+ {
+ something_happened = 1;
+ alarm_happened = 1;
+ return;
+ }
+
+ interval_id = pop_low_level_timeout (&async_timer_queue, 0);
+
+ reset_interval_timer ();
+ if (alarm_happened_while_emacs_was_blocking)
+ {
+ alarm_happened_while_emacs_was_blocking = 0;
+ waiting_for_user_input_p = 1;
+ }
+ event_stream_deal_with_async_timeout (interval_id);
+ waiting_for_user_input_p = 0;
+}
+
+#ifdef HAVE_SETITIMER
+
+unsigned int
+alarm (unsigned int howlong)
+{
+ struct itimerval old_it, new_it;
+
+ /* If alarm() gets called when polling isn't disabled, it can mess
+ up the periodic timer. */
+ assert (async_timer_suppress_count > 0);
+
+ new_it.it_value.tv_sec = howlong;
+ new_it.it_value.tv_usec = 0;
+ new_it.it_interval.tv_sec = 0;
+ new_it.it_interval.tv_usec = 0;
+ qxe_setitimer (ITIMER_REAL, &new_it, &old_it);
+
+ /* Never return zero if there was a timer outstanding. */
+ return old_it.it_value.tv_sec + (old_it.it_value.tv_usec > 0 ? 1 : 0);
+}
+
+int
+qxe_setitimer (int kind, const struct itimerval *itnew,
+ struct itimerval *itold)
+{
+#if defined (WIN32_NATIVE) || defined (CYGWIN)
+ /* setitimer() does not exist on native MS Windows, and appears broken
+ on Cygwin. See win32.c. */
+ return mswindows_setitimer (kind, itnew, itold);
+#else
+ return setitimer (kind, itnew, itold);
+#endif
+}
+
+#endif /* HAVE_SETITIMER */
+
+
+DEFUN ("waiting-for-user-input-p", Fwaiting_for_user_input_p, 0, 0, 0, /*
+Return non-nil if XEmacs is waiting for input from the user.
+This is intended for use by asynchronous timeout callbacks and by
+asynchronous process output filters and sentinels (not yet implemented
+in XEmacs). It will always be nil if XEmacs is not inside of
+an asynchronous timeout or process callback.
+*/
+ ())
+{
+ return waiting_for_user_input_p ? Qt : Qnil;
+}
+
+\f
+/**********************************************************************/
+/* Control-G checking */
+/**********************************************************************/
+
+/* Set this for debugging, to have a way to get out */
+int stop_character; /* #### not currently implemented */
+
+/* This routine is called in response to a SIGINT or SIGQUIT.
+ On TTY's, one of these two signals will get generated in response
+ to C-g. (When running under X, C-g is handled using the SIGIO
+ handler, which sets a flag telling the QUIT macro to scan the
+ unread events for a ^G.)
+
+ Otherwise it sets the Lisp variable quit-flag not-nil.
+ This causes eval to throw, when it gets a chance.
+ If quit-flag is already non-nil, it stops the job right away. */
+
+static SIGTYPE
+interrupt_signal (int sig)
+{
+ /* This function can call lisp */
+ /* #### we should NOT be calling lisp from a signal handler, boys
+ and girls */
+ /* Must preserve main program's value of errno. */
+ int old_errno = errno;
+
+ EMACS_REESTABLISH_SIGNAL (sig, interrupt_signal);
+
+/* with the macroized error-checking stuff, the garbage below
+ may mess things up because XCONSOLE() and such can use and
+ change global vars. */
+#if ! (defined (ERROR_CHECK_TYPECHECK) && defined (MACROIZE_ERROR_CHECKING))
+ if (sigint_happened && CONSOLEP (Vcontrolling_terminal) &&
+ CONSOLE_LIVE_P (XCONSOLE (Vcontrolling_terminal)) &&
+ !emacs_is_blocking)
+ {
+ char c;
+ fflush (stdout);
+ reset_initial_console ();
+ EMACS_UNBLOCK_SIGNAL (sig);
+#ifdef SIGTSTP /* Support possible in later USG versions */
+/*
+ * On systems which can suspend the current process and return to the original
+ * shell, this command causes the user to end up back at the shell.
+ * The "Auto-save" and "Abort" questions are not asked until
+ * the user elects to return to emacs, at which point he can save the current
+ * job and either dump core or continue.
+ */
+ sys_suspend ();
+#else
+ /* Perhaps should really fork an inferior shell?
+ But that would not provide any way to get back
+ to the original shell, ever. */
+ stdout_out ("No support for stopping a process on this operating system;\n");
+ stdout_out ("you can continue or abort.\n");
+#endif /* not SIGTSTP */
+ stdout_out ("Auto-save? (y or n) ");
+ if (((c = getc (stdin)) & ~040) == 'Y')
+ Fdo_auto_save (Qnil, Qnil);
+ while (c != '\n')
+ c = getc (stdin);
+ stdout_out ("Abort (and dump core)? (y or n) ");
+ if (((c = getc (stdin)) & ~040) == 'Y')
+ ABORT ();
+ while (c != '\n')
+ c = getc (stdin);
+ stdout_out ("Continuing...\n");
+ reinit_initial_console ();
+ MARK_FRAME_CHANGED (XFRAME (DEVICE_SELECTED_FRAME
+ (XDEVICE (CONSOLE_SELECTED_DEVICE
+ (XCONSOLE
+ (Vcontrolling_terminal))))));
+ }
+ else
+#endif /* ! (defined (ERROR_CHECKING) && defined (MACROIZE_ERROR_CHECKING)) */
+ {
+ /* Else request quit when it's safe */
+ Vquit_flag = Qt;
+ sigint_happened = 1;
+#ifdef HAVE_UNIXOID_EVENT_LOOP
+ signal_fake_event ();
+#endif
+ }
+ errno = old_errno;
+ SIGRETURN;
+}
+
+static Lisp_Object
+restore_dont_check_for_quit (Lisp_Object val)
+{
+ dont_check_for_quit = XINT (val);
+ return Qnil;
+}
+
+void
+begin_dont_check_for_quit (void)
+{
+ specbind (Qinhibit_quit, Qt);
+ record_unwind_protect (restore_dont_check_for_quit,
+ make_int (dont_check_for_quit));
+ dont_check_for_quit = 1;
+}
+
+/* The effect of this function is to set Vquit_flag if the user pressed
+ ^G and discard the ^G, so as to not notice the same ^G again. */
+int
+check_quit (void)
+{
+ /* dont_check_for_quit is set in two circumstances:
+
+ (1) when we are in the process of changing the window
+ configuration. The frame might be in an inconsistent state,
+ which will cause assertion failures if we check for QUIT.
+
+ (2) when we are reading events, and want to read the C-g
+ as an event. The normal check for quit will discard the C-g,
+ which would be bad.
+
+ #### C-g is still often read as quit, e.g. if you type C-x C-g
+ (the C-g happens during the sit-for in maybe_echo_keys(); even
+ if we attempt to inhibit quit here, there is still a check
+ later on for QUIT. To fix this properly requires a fairly
+ substantial overhaul of the quit-checking code, which is
+ probably not worth it.)
+
+ We should *not* conditionalize on Vinhibit_quit, or
+ critical-quit (Control-Shift-G) won't work right. */
+
+ if (dont_check_for_quit)
+ return 0;
+
+ if (quit_check_signal_happened)
+ {
+ quit_check_signal_happened = 0;
+ event_stream_quit_p ();
+ return 1;
+ }
+ else
+ return 0;
+}
+
+int
+check_what_happened (void) /* called from QUIT when
+ something_happened gets set */
+{
+ something_happened = 0;
+ if (alarm_happened)
+ {
+ alarm_happened = 0;
+ handle_alarm_going_off ();
+ }
+ return check_quit ();
+}
+
+\f
+
+void
+init_poll_for_quit (void)
+{
+#if !defined (SIGIO) && !defined (DONT_POLL_FOR_QUIT)
+ /* Check for C-g every 1/4 of a second.
+
+ #### This is just a guess. Some investigation will have to be
+ done to see what the best value is. The best value is the
+ smallest possible value that doesn't cause a significant amount
+ of running time to be spent in C-g checking. */
+ if (!poll_for_quit_id)
+ poll_for_quit_id =
+ event_stream_generate_wakeup (NORMAL_QUIT_CHECK_TIMEOUT_MSECS,
+ NORMAL_QUIT_CHECK_TIMEOUT_MSECS,
+ Qnil, Qnil, 1);
+#endif /* not SIGIO and not DONT_POLL_FOR_QUIT */
+}
+
+void
+reset_poll_for_quit (void)
+{
+#if !defined (SIGIO) && !defined (DONT_POLL_FOR_QUIT)
+ if (poll_for_quit_id)
+ {
+ event_stream_disable_wakeup (poll_for_quit_id, 1);
+ poll_for_quit_id = 0;
+ }
+#endif /* not SIGIO and not DONT_POLL_FOR_QUIT */
+}
+
+#if defined(HAVE_UNIX_PROCESSES) && !defined(SIGCHLD)
+
+static void
+init_poll_for_sigchld (void)
+{
+ /* Check for terminated processes every 1/4 of a second.
+
+ #### This is just a guess. Some investigation will have to be
+ done to see what the best value is. The best value is the
+ smallest possible value that doesn't cause a significant amount
+ of running time to be spent in process-termination checking.
+ */
+ poll_for_sigchld_id =
+ event_stream_generate_wakeup (NORMAL_SIGCHLD_CHECK_TIMEOUT_MSECS,
+ NORMAL_SIGCHLD_CHECK_TIMEOUT_MSECS,
+ Qnil, Qnil, 1);
+}
+
+#endif /* not SIGCHLD */
+
+#ifdef SIGIO
+
+static void
+input_available_signal (int signo)
+{
+ something_happened = 1; /* tell QUIT to wake up */
+ quit_check_signal_happened = 1;
+ quit_check_signal_tick_count++;
+ EMACS_REESTABLISH_SIGNAL (signo, input_available_signal);
+ SIGRETURN;
+}
+
+#endif /* SIGIO */
+
+\f
+/**********************************************************************/
+/* Enabling/disabling signals */
+/**********************************************************************/
+
+static int interrupts_initted;
+
+void
+stop_interrupts (void)
+{
+ if (!interrupts_initted)
+ return;
+#if defined(SIGIO) && !defined(BROKEN_SIGIO)
+ unrequest_sigio ();
+#endif
+ stop_async_timeouts ();
+}
+
+void
+start_interrupts (void)
+{
+ if (!interrupts_initted)
+ return;
+#if defined(SIGIO) && !defined(BROKEN_SIGIO)
+ request_sigio ();
+#endif
+ start_async_timeouts ();
+}
+
+/* Cheesy but workable implementation of sleep() that doesn't
+ interfere with our periodic timers. */
+
+void
+emacs_sleep (int secs)
+{
+ stop_interrupts ();
+ sleep (secs);
+ start_interrupts ();
+}
+
+\f
+/************************************************************************/
+/* initialization */
+/************************************************************************/
+
+/* If we've been nohup'ed, keep it that way.
+ This allows `nohup xemacs &' to work.
+ More generally, if a normally fatal signal has been redirected
+ to SIG_IGN by our invocation environment, trust the environment.
+ This keeps xemacs from being killed by a SIGQUIT intended for a
+ different process after having been backgrounded under a
+ non-job-control shell! */
+static void
+handle_signal_if_fatal (int signo)
+{
+ if (signal (signo, fatal_error_signal) == SIG_IGN)
+ signal (signo, SIG_IGN);
+}
+
+void
+init_signals_very_early (void)
+{
+ /* Catch all signals that would kill us.
+ Don't catch these signals in batch mode if not initialized.
+ On some machines, this sets static data that would make
+ signal fail to work right when the dumped Emacs is run. */
+ if (noninteractive && !initialized)
+ return;
+
+ handle_signal_if_fatal (SIGILL); /* ANSI */
+ handle_signal_if_fatal (SIGABRT); /* ANSI */
+ handle_signal_if_fatal (SIGFPE); /* ANSI */
+ handle_signal_if_fatal (SIGSEGV); /* ANSI */
+ handle_signal_if_fatal (SIGTERM); /* ANSI */
+
+
+#ifdef SIGHUP
+ handle_signal_if_fatal (SIGHUP); /* POSIX */
+#endif
+#ifdef SIGQUIT
+ handle_signal_if_fatal (SIGQUIT); /* POSIX */
+#endif
+#ifdef SIGTRAP
+ handle_signal_if_fatal (SIGTRAP); /* POSIX */
+#endif
+#ifdef SIGUSR1
+ handle_signal_if_fatal (SIGUSR1); /* POSIX */
+#endif
+#ifdef SIGUSR2
+ handle_signal_if_fatal (SIGUSR2); /* POSIX */
+#endif
+#ifdef SIGPIPE
+ handle_signal_if_fatal (SIGPIPE); /* POSIX */
+#endif
+#ifdef SIGALRM
+ /* This will get reset later, once we're
+ capable of handling it properly. */
+ handle_signal_if_fatal (SIGALRM); /* POSIX */
+#endif
+
+
+#ifdef SIGBUS
+ handle_signal_if_fatal (SIGBUS); /* XPG5 */
+#endif
+#ifdef SIGSYS
+ handle_signal_if_fatal (SIGSYS); /* XPG5 */
+#endif
+#ifdef SIGXCPU
+ handle_signal_if_fatal (SIGXCPU); /* XPG5 */
+#endif
+#ifdef SIGXFSZ
+ handle_signal_if_fatal (SIGXFSZ); /* XPG5 */
+#endif
+#ifdef SIGVTALRM
+ handle_signal_if_fatal (SIGVTALRM); /* XPG5 */
+#endif
+#ifdef SIGPROF
+ /* Messes up the REAL profiler */
+ /* handle_signal_if_fatal (SIGPROF); */ /* XPG5 */
+#endif
+
+
+#ifdef SIGHWE
+ handle_signal_if_fatal (SIGHWE);
+#endif
+#ifdef SIGPRE
+ handle_signal_if_fatal (SIGPRE);
+#endif
+#ifdef SIGORE
+ handle_signal_if_fatal (SIGORE);
+#endif
+#ifdef SIGUME
+ handle_signal_if_fatal (SIGUME);
+#endif
+#ifdef SIGDLK
+ handle_signal_if_fatal (SIGDLK);
+#endif
+#ifdef SIGCPULIM
+ handle_signal_if_fatal (SIGCPULIM);
+#endif
+#ifdef SIGIOT
+ handle_signal_if_fatal (SIGIOT);
+#endif
+#ifdef SIGEMT
+ handle_signal_if_fatal (SIGEMT);
+#endif
+#ifdef SIGLOST
+ handle_signal_if_fatal (SIGLOST);
+#endif
+#ifdef SIGSTKFLT /* coprocessor stack fault under Linux */
+ handle_signal_if_fatal (SIGSTKFLT);
+#endif
+#ifdef SIGUNUSED /* exists under Linux, and will kill process! */
+ handle_signal_if_fatal (SIGUNUSED);
+#endif
+
+#ifdef AIX
+/* 20 is SIGCHLD, 21 is SIGTTIN, 22 is SIGTTOU. */
+#ifndef _I386
+ handle_signal_if_fatal (SIGIOINT);
+#endif
+ handle_signal_if_fatal (SIGGRANT);
+ handle_signal_if_fatal (SIGRETRACT);
+ handle_signal_if_fatal (SIGSOUND);
+ handle_signal_if_fatal (SIGMSG);
+#endif /* AIX */
+
+#ifdef SIGDANGER
+ /* This just means available memory is getting low. */
+ signal (SIGDANGER, memory_warning_signal);
+#endif
+}
+
+void
+syms_of_signal (void)
+{
+ DEFSUBR (Fwaiting_for_user_input_p);
+}
+
+void
+init_interrupts_late (void)
+{
+ if (!noninteractive)
+ {
+ signal (SIGINT, interrupt_signal);
+#ifdef HAVE_TERMIO
+ /* On systems with TERMIO, C-g is set up for both SIGINT and SIGQUIT
+ and we can't tell which one it will give us. */
+ signal (SIGQUIT, interrupt_signal);
+#endif /* HAVE_TERMIO */
+ init_async_timeouts ();
+#ifdef SIGIO
+ signal (SIGIO, input_available_signal);
+# ifdef SIGPOLL /* XPG5 */
+ /* Some systems (e.g. Motorola SVR4) losingly have different
+ values for SIGIO and SIGPOLL, and send SIGPOLL instead of
+ SIGIO. On those same systems, an uncaught SIGPOLL kills the
+ process. */
+ signal (SIGPOLL, input_available_signal);
+# endif
+#elif !defined (DONT_POLL_FOR_QUIT)
+ init_poll_for_quit ();
+#endif
+ }
+
+#if defined(HAVE_UNIX_PROCESSES) && !defined(SIGCHLD)
+ init_poll_for_sigchld ();
+#endif
+
+ EMACS_UNBLOCK_ALL_SIGNALS ();
+
+ interrupts_initted = 1;
+}
+