summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--includes/RtsAPI.h4
-rw-r--r--rts/Linker.c1
-rw-r--r--rts/RtsSignals.h1
-rw-r--r--rts/RtsStartup.c25
-rw-r--r--rts/posix/Signals.c27
-rw-r--r--rts/win32/ConsoleHandler.c6
6 files changed, 60 insertions, 4 deletions
diff --git a/includes/RtsAPI.h b/includes/RtsAPI.h
index 54fa3ee560..99aaa59ffb 100644
--- a/includes/RtsAPI.h
+++ b/includes/RtsAPI.h
@@ -45,6 +45,10 @@ extern void setProgArgv ( int argc, char *argv[] );
extern void getFullProgArgv ( int *argc, char **argv[] );
extern void setFullProgArgv ( int argc, char *argv[] );
+#ifndef mingw32_HOST_OS
+extern void shutdownHaskellAndSignal (int sig);
+#endif
+
/* exit() override */
extern void (*exitFn)(int);
diff --git a/rts/Linker.c b/rts/Linker.c
index db495dde78..27c580b67f 100644
--- a/rts/Linker.c
+++ b/rts/Linker.c
@@ -174,6 +174,7 @@ typedef struct _RtsSymbolVal {
#if !defined (mingw32_HOST_OS)
#define RTS_POSIX_ONLY_SYMBOLS \
+ SymX(shutdownHaskellAndSignal) \
Sym(lockFile) \
Sym(unlockFile) \
SymX(signal_handlers) \
diff --git a/rts/RtsSignals.h b/rts/RtsSignals.h
index 721561e5b6..77f22249b2 100644
--- a/rts/RtsSignals.h
+++ b/rts/RtsSignals.h
@@ -40,6 +40,7 @@ extern void initUserSignals(void);
* Ctrl+C handler that shuts down the RTS in an orderly manner.
*/
extern void initDefaultHandlers(void);
+extern void resetDefaultHandlers(void);
extern void freeSignalHandlers(void);
diff --git a/rts/RtsStartup.c b/rts/RtsStartup.c
index c55fdfb537..f221ad8b13 100644
--- a/rts/RtsStartup.c
+++ b/rts/RtsStartup.c
@@ -71,6 +71,9 @@
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
#if USE_PAPI
#include "Papi.h"
@@ -383,6 +386,8 @@ hs_exit_(rtsBool wait_foreign)
/* start timing the shutdown */
stat_startExit();
+ OnExitHook();
+
#if defined(RTS_USER_SIGNALS)
if (RtsFlags.MiscFlags.install_signal_handlers) {
freeSignalHandlers();
@@ -440,6 +445,9 @@ hs_exit_(rtsBool wait_foreign)
PAR_TICKY_PAR_END();
#endif
+ // uninstall signal handlers
+ resetDefaultHandlers();
+
/* stop timing the shutdown, we're about to print stats */
stat_endExit();
@@ -528,10 +536,10 @@ shutdownHaskell(void)
void
shutdownHaskellAndExit(int n)
{
- if (hs_init_count == 1) {
- OnExitHook();
- hs_exit_(rtsFalse);
- // we're about to exit(), no need to wait for foreign calls to return.
+ // we're about to exit(), no need to wait for foreign calls to return.
+ hs_exit_(rtsFalse);
+
+ if (hs_init_count == 0) {
#if defined(PAR)
/* really exit (stg_exit() would call shutdownParallelSystem() again) */
exit(n);
@@ -541,6 +549,15 @@ shutdownHaskellAndExit(int n)
}
}
+#ifndef mingw32_HOST_OS
+void
+shutdownHaskellAndSignal(int sig)
+{
+ hs_exit_(rtsFalse);
+ kill(getpid(),sig);
+}
+#endif
+
/*
* called from STG-land to exit the program
*/
diff --git a/rts/posix/Signals.c b/rts/posix/Signals.c
index fcfa1f1214..e34190c439 100644
--- a/rts/posix/Signals.c
+++ b/rts/posix/Signals.c
@@ -496,6 +496,33 @@ initDefaultHandlers(void)
#ifdef alpha_HOST_ARCH
ieee_set_fp_control(0);
#endif
+
+ // ignore SIGPIPE; see #1619
+ action.sa_handler = SIG_IGN;
+ sigemptyset(&action.sa_mask);
+ action.sa_flags = 0;
+ if (sigaction(SIGPIPE, &action, &oact) != 0) {
+ sysErrorBelch("warning: failed to install SIGPIPE handler");
+ }
+}
+
+void
+resetDefaultHandlers(void)
+{
+ struct sigaction action;
+
+ action.sa_handler = SIG_DFL;
+ sigemptyset(&action.sa_mask);
+ action.sa_flags = 0;
+
+ // restore SIGINT
+ if (sigaction(SIGINT, &action, NULL) != 0) {
+ sysErrorBelch("warning: failed to uninstall SIGINT handler");
+ }
+ // restore SIGPIPE
+ if (sigaction(SIGPIPE, &action, NULL) != 0) {
+ sysErrorBelch("warning: failed to uninstall SIGPIPE handler");
+ }
}
void
diff --git a/rts/win32/ConsoleHandler.c b/rts/win32/ConsoleHandler.c
index 2cd10ecc2d..25472cf583 100644
--- a/rts/win32/ConsoleHandler.c
+++ b/rts/win32/ConsoleHandler.c
@@ -119,6 +119,12 @@ void initDefaultHandlers(void)
}
}
+void resetDefaultHandlers(void)
+{
+ if ( !SetConsoleCtrlHandler(shutdown_handler, FALSE) ) {
+ errorBelch("warning: failed to uninstall default console handler");
+ }
+}
/*
* Function: blockUserSignals()