spy-0.10: src/Spy/Run.hs
{-# LANGUAGE DoAndIfThenElse #-}
module Spy.Run (
runIndefinitely
) where
import System.IO (isEOF)
import System.Exit
import System.Posix.Signals
import Control.Concurrent
import qualified Control.Exception as E
-- | Run indefinitely until the users aborts (via CTRL-D, CTRL-C or by sending a TERM
-- signal)
-- The `start` funtion will be called once, the cleanup once when the user
-- aborts with the result of the start function as the argument.
runIndefinitely :: IO b -> (b -> IO a) -> IO ()
runIndefinitely start cleanup = do
tid <- myThreadId
res <- start
let handler = CatchOnce . terminate res tid
installHandler sigINT (handler 130) Nothing -- CTRL-C
installHandler sigTERM (handler 143) Nothing
loop res
where loop res = do
finished <- isEOF
if finished then do
cleanup res
return ()
else do
_ <- getLine
loop res
terminate res tid exit = do
cleanup res
E.throwTo tid $ ExitFailure exit