-- 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.4.2 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, daemonize -- taking an IO action which represents the daemon's actual -- activity. -- -- Briefly, daemonize sets the file creation mask to 0, forks -- twice, changed the working directory to /, closes stdin, -- stdout, and stderr, blocks sigHUP, 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 -- --
--   daemonize (forever $ return ())
--   
-- -- which does nothing until killed. daemonize :: IO () -> IO () -- | serviced turns a program into a UNIX daemon (system service) -- ready to be deployed to etcrc.d or similar startup folder. It -- is meant to be used in the main function of a program, such -- as -- --
--   serviced simpleDaemon
--   
-- -- The resulting program takes one of three arguments: start, -- stop, and restart. 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 -- varrun/$name.pid, where $name is the executable's -- name. For obvious reasons, this file is known as a PID file. -- -- start 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. -- -- stop 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. -- -- restart is simple stop followed by start. -- -- serviced 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 daemon. 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 CreateDaemon -- 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 CreateDaemon -- record passed to serviced. You can also take a predefined form -- of CreateDaemon, such as simpleDaemon 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 -> 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 main -- function. Its argument is the result of running -- privilegedAction 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 Nothing, 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 Nothing, 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 daemon. user :: CreateDaemon a -> Maybe String -- | group 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 []. syslogOptions :: CreateDaemon a -> [Option] -- | The directory where the daemon should write and look for the PID file. -- Nothing means varrun. Unless you have a good -- reason to do otherwise, leave this as Nothing. pidfileDirectory :: CreateDaemon a -> Maybe FilePath -- | The simplest possible instance of CreateDaemon is -- --
--   CreateDaemon {
--    privilegedAction = return ()
--    program = const $ forever $ return ()
--    name = Nothing,
--    user = Nothing,
--    group = Nothing,
--    syslogOptions = [],
--    pidfileDirectory = Nothing,
--   }
--   
-- -- which does nothing forever with all default settings. We give it a -- name, simpleDaemon, 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