úÎB @±   1The details of any given daemon are fixed by the   record passed to  '. You can also take a predefined form  of  , such as   below, and set what C options you want, rather than defining the whole record yourself. ,The actual guts of the daemon, more or less  the main function. )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  , in which case the $ system defaults to the name of the ( executable file containing the daemon. (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   , 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.  is the group the daemon should * try to run as, and works the same way as  the user field. %The options the daemon should set on ' syslog. You can safely leave this as []. The directory where the  daemon should write and look  for the PID file.    means varrun. Unless you  have a good reason to do  otherwise, leave this as   . 8Turning a process into a daemon involves a fixed set of B 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,   taking an  # action which represents the daemon's  actual activity.  Briefly, 0 sets the file creation mask to 0, forks twice, " changed the working directory to /, closes stdin, stdout, and  stderr, blocks  ', and runs its argument. Strictly, it E 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.  5 turns a program into a UNIX daemon (system service)  ready to be deployed to etc$rc.d or similar startup folder. It  is meant to be used in the main function of a program, such as   serviced simpleDaemon 3The resulting program takes one of three argments: start,  stop, and restart). All control the status of a daemon by B 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 6 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 D written therein. First it does a soft kill, SIGTERM, giving the D daemon a chance to shut down cleanly, then three seconds later a 6 hard kill which the daemon cannot catch or escape. restart is simple stop followed by start.  + also tries to drop privileges. If you don' t specify a B 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. D It goes through the same sequence for group. Just to complicate A matters, the name of the daemon is by default the name of the B executable file, but can again be set to something else in the   record. AFinally, exceptions in the program are caught, logged to syslog,  and the program restarted. "The simplest possible instance of  is   CreateDaemon {  program = forever $ return ()  name = Nothing,  user = Nothing,  group = Nothing,  syslogOptions = [],  pidfileDirectory = Nothing,  } Dwhich does nothing forever with all default settings. We give it a  name,  -, since you may want to use it as a template + and modify only the fields that you need.          !hdaemonize-0.3System.Posix.Daemonize CreateDaemonprogramnameusergroup syslogOptionspidfileDirectory daemonizeserviced simpleDaemonbase Data.MaybeNothingghc-prim GHC.TypesIO unix-2.4.0.2System.Posix.SignalssigHUPforevercloseFileDescriptors blockSignal getGroupID getUserIDdropPrivilegespidFile pidExistspidReadpidWritepidLivepass