
On 08/18/2010 04:55 PM, Donn Cave wrote:
Quoth Brian Bloniarz
, IMHO the simplest fix is the patch below: simply avoid SIG_IGN, instead install a handler which does nothing. This way, an exec() restores the handler to SIG_DFL. I've included a testcase too.
I don't know enough to make a case for or against this, but the side effects are different: whether the handler does anything or not, it will interrupt some system calls. Since there are already may be a regular barrage of SIGALRMs from the GHC runtime, maybe one more such interruption can't hurt anything ... but note that we recently heard from someone in Australia with a problem on OpenSolaris where evidently these SIGALRMs were in fact interrupting hGetContents from a pipe, and no one seemed to have any notion why.
Shouldn't enabling SA_RESTART be enough to restart the syscall? I don't know all the Unices enough to guarantee that it'd be transparent, but I hope it should be. I see the SIGALRM code uses SA_RESTART too, though judging by the #ifdefs in Itimer.c, SA_RESTART must not be available everywhere. Note that unlike SIGALRM, the SIGPIPE will be sent to the thread which caused it (i.e. the caller of write()), not any other thread. So any possible damage would be limited to the calling thread.
At any rate, the affected system calls would set EAGAIN, possibly including the write(2) that's supposed to set EPIPE (though I think that would be an unusual implementation.)
I just tested linux in this scenario, it gives EPIPE as I'd expect.
Linux's SA_RESTART has been reliable in my limited experience. Do
you have an OpenSolaris install to test by any chance? The code is
below.
#include