{-# LANGUAGE CPP #-}

module System.Signal where

import Foreign.C.Types
#ifdef mingw32_HOST_OS
import Control.Exception.Base (assert)
import Foreign
#else
import           Control.Monad        (void)
import qualified System.Posix.Signals as Posix
#endif


type Signal = CInt

-- | SIGABRT - Abnormal termination
sigABRT :: Signal
sigABRT :: Signal
sigABRT = Signal
6

-- | SIGFPE - Floating-point error
sigFPE :: Signal
sigFPE :: Signal
sigFPE = Signal
8

-- | SIGILL - Illegal instruction
sigILL :: Signal
sigILL :: Signal
sigILL = Signal
4

-- | SIGINT - CTRL+C signal
sigINT :: Signal
sigINT :: Signal
sigINT = Signal
2

-- | SIGSEGV - Illegal storage access
sigSEGV :: Signal
sigSEGV :: Signal
sigSEGV = Signal
11

-- | SIGTERM - Termination request
sigTERM :: Signal
sigTERM :: Signal
sigTERM = Signal
15

type Handler = Signal -> IO ()

installHandler :: Signal -> Handler -> IO ()
#ifdef mingw32_HOST_OS
foreign import ccall "wrapper"
    genHandler:: Handler -> IO (FunPtr Handler)

foreign import ccall safe "signal.h signal"
    install:: Signal -> FunPtr Handler -> IO Signal

installHandler signal handler = do
    result <- install signal =<< genHandler handler
    return $ assert (result == 0) ()
#else
installHandler :: Signal -> Handler -> IO ()
installHandler Signal
signal Handler
handler = IO Handler -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (IO Handler -> IO ()) -> IO Handler -> IO ()
forall a b. (a -> b) -> a -> b
$ Signal -> Handler -> Maybe SignalSet -> IO Handler
Posix.installHandler Signal
signal ((SignalInfo -> IO ()) -> Handler
Posix.CatchInfo (Handler
handler Handler -> (SignalInfo -> Signal) -> SignalInfo -> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SignalInfo -> Signal
Posix.siginfoSignal)) Maybe SignalSet
forall a. Maybe a
Nothing
#endif