diff options
author | Simon Marlow <marlowsd@gmail.com> | 2012-01-03 15:35:19 +0000 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2012-01-03 16:36:35 +0000 |
commit | 0095702d8176e8a2e4417c312e85f8b33bbace96 (patch) | |
tree | dc0d9c6a231dfa2793cd4a22dfd60f4be781835d /rts/posix/Signals.c | |
parent | aa1114ed0a938c35f0a5c229ccb0a63bed7d7c09 (diff) | |
download | haskell-0095702d8176e8a2e4417c312e85f8b33bbace96.tar.gz |
In the SIGTSTP handler, throw SIGSTOP instead of re-throwing SIGTSTP
Diffstat (limited to 'rts/posix/Signals.c')
-rw-r--r-- | rts/posix/Signals.c | 28 |
1 files changed, 14 insertions, 14 deletions
diff --git a/rts/posix/Signals.c b/rts/posix/Signals.c index 95d58220cf..01d5347ae7 100644 --- a/rts/posix/Signals.c +++ b/rts/posix/Signals.c @@ -519,17 +519,28 @@ empty_handler (int sig STG_UNUSED) The trick we use is: - catch SIGTSTP - - in the handler, kill(getpid(),SIGTSTP) + - in the handler, kill(getpid(),SIGSTOP) - when this returns, restore the TTY settings This means we don't have to catch SIGCONT too. + Note we don't re-throw SIGTSTP, we throw SIGSTOP instead. This is + for a few reasons: + + - re-throwing SIGTSTP would require temporarily restoring the + default sigaction. + + - it doesn't work on certain buggy pthread implementations + (e.g. OpenBSD). + + - throwing SIGTSTP seems slightly dodgy anyway. + -------------------------------------------------------------------------- */ static void sigtstp_handler(int sig); static void set_sigtstp_action (rtsBool handle); static void -sigtstp_handler (int sig) +sigtstp_handler (int sig STG_UNUSED) { int fd; struct termios ts[3]; @@ -541,17 +552,8 @@ sigtstp_handler (int sig) } } - // de-install the SIGTSTP handler - set_sigtstp_action(rtsFalse); - // really stop the process now - { - sigset_t mask; - sigemptyset(&mask); - sigaddset(&mask, sig); - sigprocmask(SIG_UNBLOCK, &mask, NULL); - kill(getpid(), sig); - } + kill(getpid(), SIGSTOP); // on return, restore the TTY state for (fd = 0; fd <= 2; fd++) { @@ -559,8 +561,6 @@ sigtstp_handler (int sig) tcsetattr(0,TCSANOW,&ts[fd]); } } - - set_sigtstp_action(rtsTrue); } static void |