Treating POSIX signals as exceptions?

David Roundy droundy at
Mon Nov 10 10:41:32 EST 2003

I was wondering why System.Posix.Signals is as it is, and whether it could
be rewritten to use exceptions, which seems like the obvious way to handle
signals.  Of course, that requires asynchronous exceptions, but that
doesn't seem like a severe problem.

What I currently do is to use the following function

withSig :: Signal -> IO a -> IO a -> IO a
withSig s handler job = do
    id <- myThreadId
    installHandler s (Catch $ throwDynTo id s) Nothing
    job `catchDyn` catcher
        where catcher s' | s' == s = handler
              catcher s' = throwDyn s'

which just catches a given signal and throws an exception, and then catches
that exception with a given default handler.  This has the nice effect that
my 'job' can't be rudely interrupted by the user hitting ^C at just the
wrong time (since I use this to catch sigINT).  Thus, this makes bracket
work in the presence of signals, allows me to use block to avoid being
interrupted by a ^C when this could cause data corruption, etc.

(Yes, I know that the above isn't very clean, since any other process that
uses {catch,throw}Dyn on a CInt will mess things up, but creating a new
Typeable instance seemed like too much trouble.)

Is there any reason all of System.Posix.Signals couldn't be done in this
manner? Have the RTS always add a handler for each signal, which just
throws an exception.  Off the top of my head, all we'd need is one function

acceptSignals :: IO () -- tells RTS to send signal exceptions to this
                       -- thread.

We'd also need some sort of SignalException type (and of course, to define
all the signals), and the rest would be done using the existing
Control.Exception code.  And, of course, default signal handlers would need
to be converted to default exception handlers.

Is there a problem with this idea?
David Roundy

More information about the Haskell-Cafe mailing list