packages feed

hdaemonize 0.5.5 → 0.5.6

raw patch · 3 files changed

+78/−51 lines, 3 filesnew-uploaderPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ System.Posix.Daemonize: Restart :: Operation
+ System.Posix.Daemonize: Start :: Operation
+ System.Posix.Daemonize: Status :: Operation
+ System.Posix.Daemonize: Stop :: Operation
+ System.Posix.Daemonize: data Operation
+ System.Posix.Daemonize: instance GHC.Classes.Eq System.Posix.Daemonize.Operation
+ System.Posix.Daemonize: instance GHC.Show.Show System.Posix.Daemonize.Operation
+ System.Posix.Daemonize: serviced' :: CreateDaemon a -> Operation -> IO ()

Files

README.md view
@@ -1,6 +1,6 @@ `hdaemonize` =================-[![Build Status](https://travis-ci.org/greydot/hdaemonize.svg?branch=master)](https://travis-ci.org/greydot/hdaemonize)+[![Build Status](https://travis-ci.org/unprolix/hdaemonize.svg?branch=master)](https://travis-ci.org/unprolix/hdaemonize)  `hdaemonize` is a simple library that hides some of the complexities of writing UNIX daemons in Haskell.@@ -9,7 +9,7 @@ -----------  The latest version is available (BSD license) at-[GitHub](https://github.com/greydot/hdaemonize).+[GitHub](https://github.com/unprolix/hdaemonize).  Using -------@@ -60,14 +60,27 @@     # 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.+Finally, if configured to do so, `mydaemon` drops privileges by+changing its effective user/group ID. (If no user/group ID are+specified, it will continue execution as the original user and group.) +Note that if you wish to parse your own commandline arguments, you can+replace invocation of the `serviced` function with `serviced'`. This+requires specification of an `Operation` which indicates whether the+daemon should be started, stopped, restarted, or whether its status+should be queried.  Changelog --------- +* 0.5.6+    * Add `serviced'` function and `Operation` (`Start`, `Stop`, etc.) to allow invocation separated from commandline+    * Only attempt to change effective user/group ID when explicitly specified.+    * Do not attempt to set user or group to the daemon's name in the absence of a specified user or group.++* 0.5.5+    * Fix a bug where hdaemonize fails when user or group "daemon" is absent+ * 0.5.4     * Update to use hsyslog == 5. @@ -93,6 +106,8 @@  Authors -------+Jeremy Bornstein <jeremy@jeremy.org>+ Lana Black <lanablack@amok.cc>  Anton Tayanovskyy <name.surname@gmail.com>.
System/Posix/Daemonize.hs view
@@ -4,7 +4,7 @@   -- * Simple daemonization   daemonize,   -- * Building system services-  serviced, CreateDaemon(..), simpleDaemon,+  serviced, serviced', CreateDaemon(..), simpleDaemon, Operation(..),   -- * Intradaemon utilities   fatalError, exitCleanly,   -- * Logging utilities@@ -40,11 +40,13 @@ import Data.Maybe (isNothing, fromMaybe, fromJust) import System.Environment import System.Exit-import System.Posix+import System.Posix hiding (Start, Stop) import System.Posix.Syslog (Priority(..), Facility(Daemon), Option, withSyslog) import qualified System.Posix.Syslog as Log import System.FilePath.Posix (joinPath) +data Operation = Start | Stop | Restart | Status deriving (Eq, Show)+ syslog :: Priority -> ByteString -> IO () syslog pri msg = unsafeUseAsCStringLen msg (Log.syslog (Just Daemon) pri) @@ -121,11 +123,26 @@  serviced :: CreateDaemon a -> IO () serviced daemon = do+        args <- getArgs++        let mOperation :: Maybe Operation+            mOperation = case args of+              ("start" : _)   -> Just Start+              ("stop" : _)    -> Just Stop+              ("restart" : _) -> Just Restart+              ("status" : _)  -> Just Status+              _               -> Nothing++        if isNothing mOperation+          then getProgName >>= \pname -> putStrLn $ "usage: " ++ pname ++ " {start|stop|status|restart}"+          else serviced' daemon $ fromJust mOperation++serviced' :: CreateDaemon a -> Operation -> IO ()+serviced' daemon operation = do         systemName <- getProgName         let daemon' = daemon { name = if isNothing (name daemon)                                         then Just systemName else name daemon }-        args <- getArgs-        process daemon' args+        process daemon' operation     where       program' daemon = withSyslog (fromJust (name daemon)) (syslogOptions daemon) Daemon $                       do let log = syslog Notice@@ -135,12 +152,12 @@                          dropPrivileges daemon                          forever $ program daemon privVal -      process daemon ["start"] = pidExists daemon >>= f where+      process daemon Start = pidExists daemon >>= f where           f True  = do error "PID file exists. Process already running?"                        exitImmediately (ExitFailure 1)           f False = daemonize (program' daemon) -      process daemon ["stop"]  =+      process daemon Stop  =           do pid <- pidRead daemon              case pid of                Nothing  -> pass@@ -152,10 +169,10 @@                    `finally`                    removeLink (pidFile daemon) -      process daemon ["restart"] = do process daemon ["stop"]-                                      process daemon ["start"]+      process daemon Restart = do process daemon Stop+                                  process daemon Start -      process daemon ["status"] = pidExists daemon >>= f where+      process daemon Status = pidExists daemon >>= f where         f True =           do pid <- pidRead daemon              case pid of@@ -167,9 +184,6 @@                          else putStrLn $ fromJust (name daemon) ++ " is not running, but pidfile is remaining."         f False = putStrLn $ fromJust (name daemon) ++ " is not running." -      process _      _ =-        getProgName >>= \pname -> putStrLn $ "usage: " ++ pname ++ " {start|stop|status|restart}"-       -- Wait 'secs' seconds for the process to exit, checking       -- for liveness once a second.  If still alive send sigKILL.       wait :: Maybe Int -> CPid -> IO ()@@ -298,30 +312,27 @@         f (Left _)    = Nothing         f (Right uid) = Just uid +-- only drop privileges if a user is specified dropPrivileges :: CreateDaemon a -> IO ()-dropPrivileges daemon =-    do let targetUser = fromJust $ asum [ user daemon-                                        , name daemon-                                        , Just "daemon"-                                        ]-           targetGroup = fromJust $ asum [ group daemon-                                         , name daemon-                                         , Just "daemon"-                                         ]-       mud <- getUserID targetUser-       mgd <- getGroupID targetGroup-       u <- case mud of-           Nothing -> do syslog Error "Privilege drop failure, no suitable user."-                         exitImmediately (ExitFailure 1)-                         undefined-           Just ud -> pure ud-       g <- case mgd of-           Nothing -> do syslog Error "Privilege drop failure, no suitable group."-                         exitImmediately (ExitFailure 1)-                         undefined-           Just gd -> pure gd-       setGroupID g-       setUserID u+dropPrivileges daemon = do+    case group daemon of+      Nothing -> pure ()+      Just targetGroup -> do+        mud <- getGroupID targetGroup+        case mud of+          Nothing -> do syslog Error "Privilege drop failure, could not identify specified group."+                        exitImmediately (ExitFailure 1)+                        undefined+          Just gd -> setGroupID gd+    case user daemon of+      Nothing -> pure ()+      Just targetUser -> do+        mud <- getUserID targetUser+        case mud of+          Nothing -> do syslog Error "Privilege drop failure, could not identify specified user."+                        exitImmediately (ExitFailure 1)+                        undefined+          Just ud -> setUserID ud  pidFile:: CreateDaemon a -> String pidFile daemon = joinPath [dir, fromJust (name daemon) ++ ".pid"]
hdaemonize.cabal view
@@ -1,21 +1,22 @@ Name:		hdaemonize-Version:	0.5.5+Version:	0.5.6 Cabal-Version:  >= 1.6 License:	BSD3 License-file:   LICENSE-Author:         Anton Tayanovskyy, Fred Ross-Maintainer:     Lana Black <lanablack at amok dot cc>-Homepage:       http://github.com/greydot/hdaemonize+Author:         Anton Tayanovskyy, Fred Ross, Lana Black+Maintainer:     Jeremy Bornstein <jeremy@jeremy.org>+Homepage:       http://github.com/unprolix/hdaemonize Category:	System Synopsis:       Library to handle the details of writing daemons for UNIX-Description:	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).+Description:	Provides functions that help writing better UNIX daemons,+                daemonize and serviced/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). Build-Type:	Simple Extra-Source-Files:	README.md-Tested-With: GHC == 7.10.3, GHC == 8.0.2, GHC == 8.2.2+Tested-With: GHC == 8.2.2, GHC == 8.4.4, GHC == 8.6.4, GHC == 8.6.5  Library   Build-Depends:    base >= 4 && < 5@@ -33,4 +34,4 @@  source-repository head   type:     git-  location: https://github.com/greydot/hdaemonize.git+  location: https://github.com/unprolix/hdaemonize.git