
quoth Ben Franksen
Consider the following program:
import System.IO import System.IO.Error import System.Posix.Signals
main = do installHandler sigPIPE Default Nothing c <- readFile "/usr/share/dict/words" putStrLn c `catchIOError` \e -> hPutStrLn stderr (show e) hPutStrLn stderr "I survived"
Compile with ghc and run as
./test | true
As expected, you see nothing further displayed, since according to `man 7 signal` the default for SIGPIPE is to terminate the program, which happens before the exception handler has a chance to run.
Without the line where the signal handler gets installed the behavior is different: You'll see:
<stdout>: commitBuffer: resource vanished (Broken pipe) I survived
Apparently the GHC runtime does something like
installHandler sigPIPE Ignore Nothing
This is not a complaint, I find the behavior quite reasonable and much more predictable than the default (why should I not be able to catch EPIPE and continue?).
The question is whether it is documented how the GHC runtime treats signals and if yes where?
For more on this, see https://mail.haskell.org/pipermail/glasgow-haskell-users/2010-August/019082.... That thread doesn't really go into why GHC interferes with SIGPIPE. I personally would lean towards letting the operating system defaults prevail, but whatever, I don't do Haskell anyway. The discussion there is more about why Ignore, rather than SIG_IGN. Donn