-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Library to handle the details of writing daemons for UNIX
--   
--   Provides two functions that help writing better UNIX daemons,
--   daemonize and serviced: daemonize does what a daemon should do
--   (forking and closing descriptors), while serviced does that and more
--   (syslog interface, PID file writing, start-stop-restart command line
--   handling, dropping privileges).
@package hdaemonize
@version 0.5.4

module System.Posix.Daemonize

-- | Turning a process into a daemon involves a fixed set of operations on
--   unix systems, described in section 13.3 of Stevens and Rago, "Advanced
--   Programming in the Unix Environment." Since they are fixed, they can
--   be written as a single function, <a>daemonize</a> taking an <a>IO</a>
--   action which represents the daemon's actual activity.
--   
--   Briefly, <a>daemonize</a> sets the file creation mask to 0, forks
--   twice, changed the working directory to <tt>/</tt>, closes stdin,
--   stdout, and stderr, blocks <a>sigHUP</a>, and runs its argument.
--   Strictly, it should close all open file descriptors, but this is not
--   possible in a sensible way in Haskell.
--   
--   The most trivial daemon would be
--   
--   <pre>
--   daemonize (forever $ return ())
--   </pre>
--   
--   which does nothing until killed.
daemonize :: IO () -> IO ()

-- | <a>serviced</a> turns a program into a UNIX daemon (system service)
--   ready to be deployed to <i>etc</i>rc.d or similar startup folder. It
--   is meant to be used in the <tt>main</tt> function of a program, such
--   as
--   
--   <pre>
--   serviced simpleDaemon
--   </pre>
--   
--   The resulting program takes one of three arguments: <tt>start</tt>,
--   <tt>stop</tt>, and <tt>restart</tt>. All control the status of a
--   daemon by looking for a file containing a text string holding the PID
--   of any running instance. Conventionally, this file is in
--   <tt><i>var</i>run/$name.pid</tt>, where $name is the executable's
--   name. For obvious reasons, this file is known as a PID file.
--   
--   <tt>start</tt> makes the program write a PID file. If the file already
--   exists, it refuses to start, guaranteeing there is only one instance
--   of the daemon at any time.
--   
--   <tt>stop</tt> read the PID file, and terminates the process whose pid
--   is written therein. First it does a soft kill, SIGTERM, giving the
--   daemon a chance to shut down cleanly, then three seconds later a hard
--   kill which the daemon cannot catch or escape.
--   
--   <tt>restart</tt> is simple <tt>stop</tt> followed by <tt>start</tt>.
--   
--   <a>serviced</a> also tries to drop privileges. If you don't specify a
--   user the daemon should run as, it will try to switch to a user with
--   the same name as the daemon, and otherwise to user <tt>daemon</tt>. It
--   goes through the same sequence for group. Just to complicate matters,
--   the name of the daemon is by default the name of the executable file,
--   but can again be set to something else in the <a>CreateDaemon</a>
--   record.
--   
--   Finally, exceptions in the program are caught, logged to syslog, and
--   the program restarted.
serviced :: CreateDaemon a -> IO ()

-- | The details of any given daemon are fixed by the <a>CreateDaemon</a>
--   record passed to <a>serviced</a>. You can also take a predefined form
--   of <a>CreateDaemon</a>, such as <a>simpleDaemon</a> below, and set
--   what options you want, rather than defining the whole record yourself.
data CreateDaemon a
CreateDaemon :: IO a -> (a -> IO ()) -> Maybe String -> Maybe String -> Maybe String -> [Option] -> Maybe FilePath -> Maybe Int -> CreateDaemon a

-- | An action to be run as root, before permissions are dropped, e.g.,
--   binding a trusted port.
[privilegedAction] :: CreateDaemon a -> IO a

-- | The actual guts of the daemon, more or less the <tt>main</tt>
--   function. Its argument is the result of running
--   <a>privilegedAction</a> before dropping privileges.
[program] :: CreateDaemon a -> a -> IO ()

-- | The name of the daemon, which is used as the name for the PID file, as
--   the name that appears in the system logs, and as the user and group
--   the daemon tries to run as if none are explicitly specified. In
--   general, this should be <a>Nothing</a>, in which case the system
--   defaults to the name of the executable file containing the daemon.
[name] :: CreateDaemon a -> Maybe String

-- | Most daemons are initially run as root, and try to change to another
--   user so they have fewer privileges and represent less of a security
--   threat. This field specifies which user it should try to run as. If it
--   is <a>Nothing</a>, or if the user does not exist on the system, it
--   next tries to become a user with the same name as the daemon, and if
--   that fails, the user <tt>daemon</tt>.
[user] :: CreateDaemon a -> Maybe String

-- | <a>group</a> is the group the daemon should try to run as, and works
--   the same way as the user field.
[group] :: CreateDaemon a -> Maybe String

-- | The options the daemon should set on syslog. You can safely leave this
--   as <tt>[]</tt>.
[syslogOptions] :: CreateDaemon a -> [Option]

-- | The directory where the daemon should write and look for the PID file.
--   <a>Nothing</a> means <tt><i>var</i>run</tt>. Unless you have a good
--   reason to do otherwise, leave this as <a>Nothing</a>.
[pidfileDirectory] :: CreateDaemon a -> Maybe FilePath

-- | How many seconds to wait between sending sigTERM and sending sigKILL.
--   If Nothing wait forever. Default 4.
[killWait] :: CreateDaemon a -> Maybe Int

-- | The simplest possible instance of <a>CreateDaemon</a> is
--   
--   <pre>
--   CreateDaemon {
--    privilegedAction = return ()
--    program = const $ forever $ return ()
--    name = Nothing,
--    user = Nothing,
--    group = Nothing,
--    syslogOptions = [],
--    pidfileDirectory = Nothing,
--   }
--   </pre>
--   
--   which does nothing forever with all default settings. We give it a
--   name, <a>simpleDaemon</a>, since you may want to use it as a template
--   and modify only the fields that you need.
simpleDaemon :: CreateDaemon ()

-- | When you encounter an error where the only sane way to handle it is to
--   write an error to the log and die messily, use fatalError. This is a
--   good candidate for things like not being able to find configuration
--   files on startup.
fatalError :: MonadIO m => String -> m a

-- | Use this function when the daemon should terminate normally. It logs a
--   message, and exits with status 0.
exitCleanly :: MonadIO m => m a
syslog :: Priority -> ByteString -> IO ()
