{-# OPTIONS_GHC -fno-warn-unused-do-bind #-}
module Core.Program.Signal
( setupSignalHandlers
) where
import Control.Concurrent.MVar (MVar, modifyMVar_, putMVar)
import Core.Program.Context
import Foreign.C.Types (CInt)
import System.Exit (ExitCode (..))
import System.IO (hFlush, hPutStrLn, stdout)
import System.Posix.Signals
( Handler (Catch)
, installHandler
, sigINT
, sigTERM
, sigUSR1
)
code :: CInt -> ExitCode
code :: CInt -> ExitCode
code CInt
signal = Int -> ExitCode
ExitFailure (Int
128 forall a. Num a => a -> a -> a
+ forall a b. (Integral a, Num b) => a -> b
fromIntegral CInt
signal)
interruptHandler :: MVar ExitCode -> Handler
interruptHandler :: MVar ExitCode -> Handler
interruptHandler MVar ExitCode
quit = IO () -> Handler
Catch forall a b. (a -> b) -> a -> b
$ do
Handle -> String -> IO ()
hPutStrLn Handle
stdout String
"\nInterrupt"
Handle -> IO ()
hFlush Handle
stdout
forall a. MVar a -> a -> IO ()
putMVar MVar ExitCode
quit (CInt -> ExitCode
code CInt
sigINT)
terminateHandler :: MVar ExitCode -> Handler
terminateHandler :: MVar ExitCode -> Handler
terminateHandler MVar ExitCode
quit = IO () -> Handler
Catch forall a b. (a -> b) -> a -> b
$ do
Handle -> String -> IO ()
hPutStrLn Handle
stdout String
"Terminating"
Handle -> IO ()
hFlush Handle
stdout
forall a. MVar a -> a -> IO ()
putMVar MVar ExitCode
quit (CInt -> ExitCode
code CInt
sigTERM)
logLevelHandler :: MVar Verbosity -> Handler
logLevelHandler :: MVar Verbosity -> Handler
logLevelHandler MVar Verbosity
v = IO () -> Handler
Catch forall a b. (a -> b) -> a -> b
$ do
Handle -> String -> IO ()
hPutStrLn Handle
stdout String
"Signal"
Handle -> IO ()
hFlush Handle
stdout
forall a. MVar a -> (a -> IO a) -> IO ()
modifyMVar_
MVar Verbosity
v
( \Verbosity
level -> case Verbosity
level of
Verbosity
Output -> forall (f :: * -> *) a. Applicative f => a -> f a
pure Verbosity
Debug
Verbosity
Verbose -> forall (f :: * -> *) a. Applicative f => a -> f a
pure Verbosity
Debug
Verbosity
Debug -> forall (f :: * -> *) a. Applicative f => a -> f a
pure Verbosity
Output
Verbosity
Internal -> forall (f :: * -> *) a. Applicative f => a -> f a
pure Verbosity
Output
)
setupSignalHandlers :: MVar ExitCode -> MVar Verbosity -> IO ()
setupSignalHandlers :: MVar ExitCode -> MVar Verbosity -> IO ()
setupSignalHandlers MVar ExitCode
quit MVar Verbosity
level = do
CInt -> Handler -> Maybe SignalSet -> IO Handler
installHandler CInt
sigINT (MVar ExitCode -> Handler
interruptHandler MVar ExitCode
quit) forall a. Maybe a
Nothing
CInt -> Handler -> Maybe SignalSet -> IO Handler
installHandler CInt
sigTERM (MVar ExitCode -> Handler
terminateHandler MVar ExitCode
quit) forall a. Maybe a
Nothing
CInt -> Handler -> Maybe SignalSet -> IO Handler
installHandler CInt
sigUSR1 (MVar Verbosity -> Handler
logLevelHandler MVar Verbosity
level) forall a. Maybe a
Nothing
forall (m :: * -> *) a. Monad m => a -> m a
return ()