module Control.Shell.Daemon (daemonize) where
import Control.Shell hiding (stdin)
import System.Directory
import System.Exit
import System.IO
import System.Posix
daemonize :: Shell () -> Shell ()
daemonize m = do
env <- getShellEnv
unsafeLiftIO $ do
void $ setFileCreationMask 0
void $ forkProcess (p env)
exitImmediately ExitSuccess
where
p env = do
void $ createSession
void $ forkProcess (p' env)
exitImmediately ExitSuccess
p' env = do
changeWorkingDirectory "/"
devnull <- openFd "/dev/null" ReadWrite Nothing defaultFileFlags
mapM_ closeFd [stdInput, stdOutput, stdError]
mapM_ (dupTo devnull) [stdInput, stdOutput, stdError]
void $ installHandler sigHUP Ignore Nothing
dir <- getCurrentDirectory
res <- flip runSh m $ env
{ envStdIn = stdin
, envStdOut = stdout
, envStdErr = stderr
, envWorkDir = dir
, envEnvVars = envEnvVars env
}
case res of
Left (Failure _) -> exitFailure
_ -> exitSuccess