MissingH-1.6.0.3: src/System/Daemon.hs
{-# LANGUAGE CPP #-}
{-# LANGUAGE Trustworthy #-}
{-
Copyright (c) 2005-2011 John Goerzen <jgoerzen@complete.org>
All rights reserved.
For license and copyright information, see the file LICENSE
-}
{- |
Module : System.Daemon
Copyright : Copyright (C) 2005-2011 John Goerzen
SPDX-License-Identifier: BSD-3-Clause
Stability : stable
Portability: portable to platforms with POSIX process\/signal tools
Tools for writing daemons\/server processes
Written by John Goerzen, jgoerzen\@complete.org
Messages from this module are logged under @System.Daemon@. See
'System.Log.Logger' for details.
This module is not available on Windows.
-}
module System.Daemon (
#if !(defined(mingw32_HOST_OS) || defined(mingw32_TARGET_OS) || defined(__MINGW32__))
detachDaemon
#endif
)
where
#if !(defined(mingw32_HOST_OS) || defined(mingw32_TARGET_OS) || defined(__MINGW32__))
import System.Directory ( setCurrentDirectory )
import System.Exit ( ExitCode(ExitSuccess) )
import System.Log.Logger ( traplogging, Priority(ERROR) )
import System.Posix.IO
( openFd,
closeFd,
defaultFileFlags,
dupTo,
stdError,
stdInput,
stdOutput,
OpenMode(ReadWrite) )
import System.Posix.Process
( createSession, exitImmediately, forkProcess )
trap :: IO a -> IO a
trap = traplogging "System.Daemon" ERROR "detachDaemon"
{- | Detach the process from a controlling terminal and run it in the
background, handling it with standard Unix deamon semantics.
After running this, please note the following side-effects:
* The PID of the running process will change
* stdin, stdout, and stderr will not work (they'll be set to
\/dev\/null)
* CWD will be changed to \/
I /highly/ suggest running this function before starting any threads.
Note that this is not intended for a daemon invoked from inetd(1).
-}
detachDaemon :: IO ()
detachDaemon = trap $
do _ <- forkProcess child1
exitImmediately ExitSuccess
child1 :: IO ()
child1 = trap $
do _ <- createSession
_ <- forkProcess child2
exitImmediately ExitSuccess
child2 :: IO ()
child2 = trap $
do setCurrentDirectory "/"
mapM_ closeFd [stdInput, stdOutput, stdError]
nullFd <- openFd
"/dev/null"
ReadWrite
#if !MIN_VERSION_unix(2,8,0)
Nothing
#endif
defaultFileFlags
mapM_ (dupTo nullFd) [stdInput, stdOutput, stdError]
closeFd nullFd
#endif