The hdaemonize package

[Tags:bsd3, library]

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).

[Skip to Readme]


Versions 0.1, 0.2, 0.3, 0.4, 0.4.1, 0.4.2, 0.4.3, 0.4.4,,,,,, 0.5.1, 0.5.2, 0.5.3, 0.5.4
Dependencies base (==4.*), bytestring, extensible-exceptions, filepath, hsyslog (==5.*), mtl, unix [details]
License BSD3
Author Anton Tayanovskyy, Fred Ross
Maintainer Lana Black <lanablack at amok dot cc>
Category System
Home page
Source repository head: git clone
Uploaded Sun May 28 22:48:34 UTC 2017 by sickmind
Distributions LTSHaskell:0.5.3, NixOS:0.5.4, Stackage:0.5.4, Tumbleweed:0.5.3
Downloads 5046 total (372 in the last 30 days)
0 []
Status Docs available [build log]
Last success reported on 2017-05-28 [all 1 reports]
Hackage Matrix CI




Maintainer's Corner

For package maintainers and hackage trustees

Readme for hdaemonize

Readme for hdaemonize-0.5.4


Build Status

hdaemonize is a simple library that hides some of the complexities of writing UNIX daemons in Haskell.


The latest version is available (BSD license) at GitHub.


The synopsis is:

import System.Posix.Daemonize
main = daemonize $ program

This code will make program do what good daemons should do, that is, detach from the terminal, close file descriptors, create a new process group, and so on.

If you want more functionality than that, it is available as a serviced function.

Here is an example:

import Control.Concurrent
import System.Posix.Daemonize

loop i log = do threadDelay $ 10^6
                log (show i)
                writeFile "/tmp/counter" $ show i
                if i == 5 then undefined else loop (i + 1) log

main = serviced (loop 0)

Let us say this program is compiled as mydaemon. Then:

# mydaemon start

starts the service. A second call to start will complain that the program is already running.

During its execution, mydaemon will simply write a new number to /tmp/counter every second, until it reaches 5. Then, an exception will be thrown. This exception will be caught by hdaemonize, and logged to /var/log/daemon.log or similar (this is depends on how syslog works on your platorm). log (show i) will leave messages in the same file.

When the exception is thrown, the program will be restared in 5 seconds, and will start counting from 0 again.

The following commands are also made available:

# mydaemon stop
# mydaemon restart

Finally, mydaemon drops privileges. By default it changes the effective user and group ids to those of the daemon user, but it prefers to use those of mydaemon, if present.


  • 0.5.2

    • Fix pre-AMP builds.
  • 0.5.1

    • Updated to use hsyslog >=4
  • 0.4

    • added support for a privileged action before dropping privileges
  • 0.3

    • merged with updates by madhadron
  • 0.2

    • provided documentation
    • backported to older GHC versions, tested on 6.8.1
  • 0.1

    • initial public release


Lana Black

Anton Tayanovskyy

The code is originally based on a public posting by Andre Nathan, used by permission.