[project @ 2001-07-22 03:28:25 by chak]
[ghc-hetmet.git] / ghc / rts / Signals.c
index 90b46ba..037e427 100644 (file)
@@ -1,5 +1,5 @@
 /* -----------------------------------------------------------------------------
- * $Id: Signals.c,v 1.14 2000/02/29 14:38:19 simonmar Exp $
+ * $Id: Signals.c,v 1.19 2001/01/24 15:38:14 simonmar Exp $
  *
  * (c) The GHC Team, 1998-1999
  *
@@ -7,6 +7,8 @@
  *
  * ---------------------------------------------------------------------------*/
 
+#define NON_POSIX_SOURCE
+
 #include "Rts.h"
 #include "SchedAPI.h"
 #include "Schedule.h"
@@ -19,6 +21,7 @@
 
 #ifndef PAR
 
+/* SUP: The type of handlers is a little bit, well, doubtful... */
 static StgInt *handlers = NULL; /* Dynamically grown array of signal handlers */
 static StgInt nHandlers = 0;    /* Size of handlers array */
 
@@ -97,7 +100,7 @@ generic_handler(int sig)
        circumstances, depending on the signal.  
     */
 
-    *next_pending_handler++ = deRefStablePtr(handlers[sig]);
+    *next_pending_handler++ = deRefStablePtr(stgCast(StgStablePtr,handlers[sig]));
 
     /* stack full? */
     if (next_pending_handler == &pending_handler_buf[N_PENDING_HANDLERS]) {
@@ -143,7 +146,7 @@ unblockUserSignals(void)
    -------------------------------------------------------------------------- */
 
 StgInt 
-sig_install(StgInt sig, StgInt spi, StgStablePtr handler, sigset_t *mask)
+stg_sig_install(StgInt sig, StgInt spi, StgStablePtr handler, sigset_t *mask)
 {
     sigset_t signals;
     struct sigaction action;
@@ -179,7 +182,7 @@ sig_install(StgInt sig, StgInt spi, StgStablePtr handler, sigset_t *mask)
        break;
 
     default:
-        barf("sig_install: bad spi");
+        barf("stg_sig_install: bad spi");
     }
 
     if (mask != 0)
@@ -196,7 +199,7 @@ sig_install(StgInt sig, StgInt spi, StgStablePtr handler, sigset_t *mask)
        * by freeing the previous handler if there was one.
        */       
       if (previous_spi >= 0) {
-         freeStablePtr(handlers[sig]);
+         freeStablePtr(stgCast(StgStablePtr,handlers[sig]));
       }
       return STG_SIG_ERR;
     }
@@ -217,8 +220,9 @@ start_signal_handlers(void)
 
     next_pending_handler--;
 
-    createIOThread(RtsFlags.GcFlags.initialStkSize, 
-                  (StgClosure *) *next_pending_handler);
+    scheduleThread(
+       createIOThread(RtsFlags.GcFlags.initialStkSize, 
+                     (StgClosure *) *next_pending_handler));
   }
 
   unblockUserSignals();
@@ -226,7 +230,7 @@ start_signal_handlers(void)
 
 #else /* PAR */
 StgInt 
-sig_install(StgInt sig, StgInt spi, StgStablePtr handler, sigset_t *mask)
+stg_sig_install(StgInt sig, StgInt spi, StgStablePtr handler, sigset_t *mask)
 {
   /* don't fflush(stdout); WORKAROUND bug in Linux glibc */
   barf("no signal handling support in a parallel implementation");
@@ -263,7 +267,15 @@ shutdown_handler(int sig STG_UNUSED)
   } else
 #endif
 
-    interruptStgRts();
+  /* 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();
+  }
 }
 
 /*
@@ -273,10 +285,6 @@ shutdown_handler(int sig STG_UNUSED)
  * 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.
- *
- * We ignore SIGPIPE, because our I/O library handles EPIPE properly,
- * and a SIGPIPE tends to cause the program to exit silently and
- * mysteriously.
  */
 void
 init_default_handlers()
@@ -294,10 +302,7 @@ init_default_handlers()
       prog_belch("failed to install SIGINT handler");
     }
 
-    action.sa_handler = SIG_IGN;
-    if (sigaction(SIGPIPE, &action, &oact) != 0) {
-      prog_belch("failed to install SIGINT handler");
-    }
+    siginterrupt(SIGINT, 1);
 }
 
 #endif /*! mingw32_TARGET_OS */