diff --git a/System/Daemonize.hs b/System/Daemonize.hs
--- a/System/Daemonize.hs
+++ b/System/Daemonize.hs
@@ -18,7 +18,6 @@
 
 data DaemonOptions = DaemonOptions {
     daemonShouldChangeDirectory :: Bool,
-    daemonShouldRedirectStandardStreams :: Bool,
     daemonShouldCloseStandardStreams :: Bool,
     daemonShouldIgnoreSignals :: Bool,
     daemonUserToChangeTo :: Maybe String,
@@ -29,7 +28,6 @@
 defaultDaemonOptions :: DaemonOptions
 defaultDaemonOptions = DaemonOptions {
                          daemonShouldChangeDirectory = True,
-                         daemonShouldRedirectStandardStreams = False,
                          daemonShouldCloseStandardStreams = True,
                          daemonShouldIgnoreSignals = True,
                          daemonUserToChangeTo = Nothing,
@@ -37,38 +35,18 @@
                        }
 
 
-foreign import ccall "daemon" c_daemon :: CInt -> CInt -> IO CInt
-
-
-daemonize :: DaemonOptions -> IO () -> IO ()
-daemonize options action = do
-  case daemonGroupToChangeTo options of
-    Nothing -> return ()
-    Just groupName -> do
-      groupEntry <- POSIX.getGroupEntryForName groupName
-      POSIX.setGroupID $ POSIX.groupID groupEntry
-  case daemonUserToChangeTo options of
-    Nothing -> return ()
-    Just userName -> do
-      userEntry <- POSIX.getUserEntryForName userName
-      POSIX.setUserID $ POSIX.userID userEntry
-  _ <- POSIX.forkProcess $ daemonize' options action
+daemonize :: DaemonOptions -> IO a -> (a -> IO ()) -> IO ()
+daemonize options privilegedAction mainAction = do
+  _ <- POSIX.forkProcess $ daemonize' options privilegedAction mainAction
   POSIX.exitImmediately ExitSuccess
 
 
-daemonize' :: DaemonOptions -> IO () -> IO ()
-daemonize' options action = do
-  let c_shouldChangeDirectory
-        = if daemonShouldChangeDirectory options
-            then 0
-            else 1
-      c_shouldRedirectStandardStreams
-        = if daemonShouldRedirectStandardStreams options
-            then 0
-            else 1
-  throwErrnoIfMinus1 "daemonize"
-                     $ c_daemon c_shouldChangeDirectory
-                                c_shouldRedirectStandardStreams
+daemonize' :: DaemonOptions -> IO a -> (a -> IO ()) -> IO ()
+daemonize' options privilegedAction mainAction = do
+  _ <- POSIX.createSession
+  if daemonShouldChangeDirectory options
+    then POSIX.changeWorkingDirectory "/"
+    else return ()
   if daemonShouldIgnoreSignals options
     then do
       POSIX.installHandler POSIX.sigTTOU POSIX.Ignore Nothing
@@ -76,7 +54,18 @@
       POSIX.installHandler POSIX.sigTSTP POSIX.Ignore Nothing
       return ()
     else return ()
+  privilegedResult <- privilegedAction
   if daemonShouldCloseStandardStreams options
     then mapM_ hClose [stdin, stdout, stderr]
     else return ()
-  action
+  case daemonGroupToChangeTo options of
+    Nothing -> return ()
+    Just groupName -> do
+      groupEntry <- POSIX.getGroupEntryForName groupName
+      POSIX.setGroupID $ POSIX.groupID groupEntry
+  case daemonUserToChangeTo options of
+    Nothing -> return ()
+    Just userName -> do
+      userEntry <- POSIX.getUserEntryForName userName
+      POSIX.setUserID $ POSIX.userID userEntry
+  mainAction privilegedResult
diff --git a/direct-daemonize.cabal b/direct-daemonize.cabal
--- a/direct-daemonize.cabal
+++ b/direct-daemonize.cabal
@@ -1,5 +1,5 @@
 name: direct-daemonize
-version: 3.0
+version: 3.1
 cabal-version: >= 1.12
 build-type: Simple
 license: BSD3
@@ -7,26 +7,36 @@
 copyright: Copyright (c) 2012 Irene Knapp
 author: Irene Knapp <ireney.knapp@gmail.com>
 maintainer: ireney.knapp@gmail.com
-homepage: http://ireneknapp.com/software/
-bug-reports: http://ireneknapp.com/issues/create/
+homepage: http://dankna.com/software/
+bug-reports: http://dankna.com/issues/create/
 category: System
 synopsis: Library to switch to daemon mode using built-in OS facilities.
 description:
   This package is a wrapper around the daemon() function on BSD-like Unices,
   including Mac OS X and glibc-based Linux distributions.  It does not function
   on other systems.
-  
+  .
+  Version 3.1 adds the ability to do something after forking but before
+  dropping privileges.  It also no longer uses the system-provided daemon()
+  function, which is highly unfortunate but necessary with the RTS's use of
+  per-process timers.
+  .
+  Version 3.0.0.1 updates this documentation to be properly broken into
+  paragraphs.
+  .
   Version 3.0 cleans up the parameters structure.
-  
+  .
   Version 2.0 fixes compatibility problems with the threaded GHC runtime.
-  Doing this required two non-backwards-compatible API changes.  First, the daemonize function now takes an action to perform as a daemon, and never
+  Doing this required two non-backwards-compatible API changes.  First, the
+  daemonize function now takes an action to perform as a daemon, and never
   returns.  Second, the functionality of closing all open files has been
   removed, as it caused crashes.  As a substitute, the option of closing only
   the three standard streams has been added and made the default.
+  .
+  Version 1.0 was the initial release.
 
 Library
   exposed-modules: System.Daemonize
   build-depends: base >= 4.1 && < 5,
                  unix >= 2.4.0.1
   default-language: Haskell2010
-
