+
+/* -----------------------------------------------------------------------------
+ SIGINT handler.
+
+ We like to shutdown nicely after receiving a SIGINT, write out the
+ stats, write profiling info, close open files and flush buffers etc.
+ -------------------------------------------------------------------------- */
+
+#ifdef SMP
+pthread_t startup_guy;
+#endif
+
+static void
+shutdown_handler(int sig STG_UNUSED)
+{
+#ifdef SMP
+ /* if I'm a worker thread, send this signal to the guy who
+ * originally called startupHaskell(). Since we're handling
+ * the signal, it won't be a "send to all threads" type of signal
+ * (according to the POSIX threads spec).
+ */
+ if (pthread_self() != startup_guy) {
+ pthread_kill(startup_guy, sig);
+ } else
+#endif
+
+ /* If we're already trying to interrupt the RTS, terminate with
+ * extreme prejudice. So the first ^C tries to exit the program
+ * cleanly, and the second one just kills it.
+ */
+ if (interrupted) {
+ exit(EXIT_INTERRUPTED);
+ } else {
+ interruptStgRts();
+ }
+}
+
+/*
+ * The RTS installs a default signal handler for catching
+ * SIGINT, so that we can perform an orderly shutdown.
+ *
+ * Haskell code may install their own SIGINT handler, which is
+ * fine, provided they're so kind as to put back the old one
+ * when they de-install.
+ *
+ * In addition to handling SIGINT, the RTS also handles SIGFPE
+ * by ignoring it. Apparently IEEE requires floating-point
+ * exceptions to be ignored by default, but alpha-dec-osf3
+ * doesn't seem to do so.
+ */
+void
+init_default_handlers()
+{
+ struct sigaction action,oact;
+
+#ifdef SMP
+ startup_guy = pthread_self();
+#endif
+ action.sa_handler = shutdown_handler;
+ sigemptyset(&action.sa_mask);
+ action.sa_flags = 0;
+ if (sigaction(SIGINT, &action, &oact) != 0) {
+ /* Oh well, at least we tried. */
+ prog_belch("failed to install SIGINT handler");
+ }
+
+ siginterrupt(SIGINT, 1);
+
+ action.sa_handler = SIG_IGN;
+ sigemptyset(&action.sa_mask);
+ action.sa_flags = 0;
+ if (sigaction(SIGFPE, &action, &oact) != 0) {
+ /* Oh well, at least we tried. */
+ prog_belch("failed to install SIGFPE handler");
+ }
+#ifdef alpha_TARGET_ARCH
+ ieee_set_fp_control(0);
+#endif
+}
+
+#endif /*! mingw32_TARGET_OS */