module Program.Mighty.Network (
daemonize
) where
import Control.Monad
import System.Exit
import System.Posix
daemonize :: IO () -> IO ()
daemonize :: IO () -> IO ()
daemonize IO ()
program = IO () -> IO ()
forall b. IO () -> IO b
ensureDetachTerminalCanWork (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
IO ()
detachTerminal
IO () -> IO ()
forall b. IO () -> IO b
ensureNeverAttachTerminal (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
FilePath -> IO ()
changeWorkingDirectory FilePath
"/"
IO FileMode -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (IO FileMode -> IO ()) -> IO FileMode -> IO ()
forall a b. (a -> b) -> a -> b
$ FileMode -> IO FileMode
setFileCreationMask FileMode
0
(Fd -> IO ()) -> [Fd] -> IO ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ Fd -> IO ()
closeFd [Fd
stdInput, Fd
stdOutput, Fd
stdError]
IO ()
program
where
ensureDetachTerminalCanWork :: IO () -> IO b
ensureDetachTerminalCanWork IO ()
p = do
IO ProcessID -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (IO ProcessID -> IO ()) -> IO ProcessID -> IO ()
forall a b. (a -> b) -> a -> b
$ IO () -> IO ProcessID
forkProcess IO ()
p
IO b
forall a. IO a
exitSuccess
ensureNeverAttachTerminal :: IO () -> IO b
ensureNeverAttachTerminal IO ()
p = do
IO ProcessID -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (IO ProcessID -> IO ()) -> IO ProcessID -> IO ()
forall a b. (a -> b) -> a -> b
$ IO () -> IO ProcessID
forkProcess IO ()
p
IO b
forall a. IO a
exitSuccess
detachTerminal :: IO ()
detachTerminal = IO ProcessID -> IO ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void IO ProcessID
createSession