angel-0.4.4: src/Angel/PidFile.hs
module Angel.PidFile ( startMaybeWithPidFile
, startWithPidFile
, clearPIDFile) where
import Control.Applicative ( (<$>)
, (<*>) )
import Control.Exception.Base ( catch
, finally
, SomeException)
import Control.Monad (when)
import System.Process ( CreateProcess
, createProcess
, ProcessHandle )
-- Wish I didn't have to do this :(
import System.Process.Internals ( PHANDLE
, ProcessHandle__(..)
, withProcessHandle
)
import System.Posix.Files ( removeLink
, fileExist)
startMaybeWithPidFile :: CreateProcess -> Maybe FilePath -> (ProcessHandle -> IO a) -> IO a
startMaybeWithPidFile procSpec (Just pidFile) = startWithPidFile procSpec pidFile
startMaybeWithPidFile procSpec Nothing = withPHandle procSpec
startWithPidFile :: CreateProcess -> FilePath -> (ProcessHandle -> IO a) -> IO a
startWithPidFile procSpec pidFile action = do
withPHandle procSpec $ \pHandle -> do
mPid <- getPID pHandle
maybe (return ()) write mPid
action pHandle `finally` clearPIDFile pidFile
where write = writePID pidFile
withPHandle :: CreateProcess -> (ProcessHandle -> IO a) -> IO a
withPHandle procSpec action = do
(_, _, _, pHandle) <- createProcess procSpec
action pHandle
writePID :: FilePath -> PHANDLE -> IO ()
writePID pidFile = writeFile pidFile . show
clearPIDFile :: FilePath -> IO ()
clearPIDFile pidFile = do ex <- fileExist pidFile
when ex rm
where exists = fileExist pidFile
rm = removeLink pidFile
getPID :: ProcessHandle -> IO (Maybe PHANDLE)
getPID pHandle = withProcessHandle pHandle getPID'
where getPID' h @ (OpenHandle t) = return (h, Just t)
getPID' h @ (ClosedHandle t) = return (h, Nothing)