]> gitweb.michael.orlitzky.com - dead/htsn.git/blobdiff - src/Unix.hs
Add the *.cabal file to the `make doc` dependencies.
[dead/htsn.git] / src / Unix.hs
index 893132624165566232ae1da28bd698faea2f6465..9b0ddaac9d3bbc10dc532b87c233378be2dd19cb 100644 (file)
@@ -1,3 +1,5 @@
+-- | Non-portable code for daemonizing on unix.
+--
 module Unix
 where
 
@@ -17,6 +19,7 @@ import System.Posix (
   getUserEntryForName,
   installHandler,
   removeLink,
+  setFileCreationMask,
   setGroupID,
   setUserID,
   sigTERM )
@@ -28,29 +31,55 @@ import Configuration (
                  run_as_user ))
 import Logging ( log_info )
 
+-- | Retrieve the uid associated with the given system user name. We
+--   take a Maybe String as an argument so the user name can be passed
+--   in directly from the config.
+--
 get_user_id :: Maybe String -> IO UserID
 get_user_id Nothing  = getRealUserID
 get_user_id (Just s) = fmap userID (getUserEntryForName s)
 
+
+-- | Retrieve the gid associated with the given system group name. We
+--   take a Maybe String as an argument so the group name can be
+--   passed in directly from the config.
+--
 get_group_id :: Maybe String -> IO GroupID
 get_group_id Nothing  = getRealGroupID
 get_group_id (Just s) = fmap groupID (getGroupEntryForName s)
 
+
+-- | This function will be called in response to a SIGTERM; i.e. when
+--   someone tries to kill our process. We simply delete the PID file
+--   and signal our parent thread to quit (successfully).
 graceful_shutdown :: Configuration -> ThreadId -> IO ()
 graceful_shutdown cfg main_thread_id = do
   log_info "SIGTERM received, removing PID file and shutting down."
   removeLink (pidfile cfg)
   throwTo main_thread_id ExitSuccess
 
+
+-- | Write a PID file, install a SIGTERM handler, drop privileges, and
+--   finally do the daemonization dance.
+--
 full_daemonize :: Configuration -> IO () -> IO ()
 full_daemonize cfg program = do
+  -- The call to 'daemonize' will set the umask to zero, but we want
+  -- to retain it. So, we set the umask to zero before 'daemonize'
+  -- can, so that we can record the previous umask value (returned by
+  -- setFileCreationMask).
+  orig_umask <- setFileCreationMask 0
   -- This is the 'daemonize' from System.Posix.Daemonize.
-  daemonize program'
+  daemonize (program' orig_umask)
   where
     -- We need to do all this stuff *after* we daemonize.
-    program' = do
+    program' orig_umask = do
       -- First write the PID file which probably requires root.
       pid <- getProcessID
+
+      -- The PID file needs to be read-only for anyone but its
+      -- owner. Hopefully the umask accomplishes this!
+      _ <- setFileCreationMask orig_umask
       writeFile (pidfile cfg) (show pid)
 
       -- We need to pass the thread ID to the signal handler so it