summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2012-06-11 02:01:20 -0400
committerGravatar Joey Hess <joey@kitenet.net>2012-06-11 02:01:20 -0400
commitd0a0a6ae21e71c83c6365500a4f9b78f38477ac0 (patch)
treef28ca5157381372986d69f00e4535cec712a28fd
parent8539a7bde8e20758b7f7d70af93fe92aa4be1e7f (diff)
git annex watch --stop
-rw-r--r--Command/Watch.hs33
-rw-r--r--Utility/Daemon.hs33
-rw-r--r--doc/git-annex.mdwn3
3 files changed, 49 insertions, 20 deletions
diff --git a/Command/Watch.hs b/Command/Watch.hs
index 8b8e5578d..f01a9616f 100644
--- a/Command/Watch.hs
+++ b/Command/Watch.hs
@@ -50,27 +50,36 @@ data Change = Change
deriving (Show)
def :: [Command]
-def = [withOptions [foregroundOption] $
+def = [withOptions [foregroundOption, stopOption] $
command "watch" paramPaths seek "watch for changes"]
seek :: [CommandSeek]
-seek = [withFlag foregroundOption $ withNothing . start]
+seek = [withFlag stopOption $ \stopdaemon ->
+ withFlag foregroundOption $ \foreground ->
+ withNothing $ start foreground stopdaemon]
foregroundOption :: Option
foregroundOption = Option.flag [] "foreground" "do not daemonize"
-start :: Bool -> CommandStart
-start foreground = notBareRepo $ withStateMVar $ \st -> do
- if foreground
- then do
- showStart "watch" "."
- liftIO $ watch st
- else do
- logfd <- liftIO . openLog =<< fromRepo gitAnnexLogFile
- pidfile <- fromRepo gitAnnexPidFile
- liftIO $ daemonize logfd (Just pidfile) False $ watch st
+stopOption :: Option
+stopOption = Option.flag [] "stop" "stop daemon"
+
+start :: Bool -> Bool -> CommandStart
+start foreground stopdaemon = notBareRepo $ do
+ if stopdaemon
+ then liftIO . stopDaemon =<< fromRepo gitAnnexPidFile
+ else withStateMVar $ startDaemon (not foreground)
stop
+startDaemon :: Bool -> MVar Annex.AnnexState -> Annex ()
+startDaemon False st = do
+ showStart "watch" "."
+ liftIO $ watch st
+startDaemon True st = do
+ logfd <- liftIO . openLog =<< fromRepo gitAnnexLogFile
+ pidfile <- fromRepo gitAnnexPidFile
+ liftIO $ daemonize logfd (Just pidfile) False $ watch st
+
watch :: MVar Annex.AnnexState -> IO ()
#if defined linux_HOST_OS
watch st = withINotify $ \i -> do
diff --git a/Utility/Daemon.hs b/Utility/Daemon.hs
index b41ebe228..b09dce739 100644
--- a/Utility/Daemon.hs
+++ b/Utility/Daemon.hs
@@ -27,7 +27,7 @@ daemonize logfd pidfile changedirectory a = do
_ <- forkProcess child2
out
child2 = do
- maybe noop lockPidFile pidfile
+ maybe noop (lockPidFile True alreadyrunning) pidfile
when changedirectory $
setCurrentDirectory "/"
nullfd <- openFd "/dev/null" ReadOnly Nothing defaultFileFlags
@@ -39,12 +39,31 @@ daemonize logfd pidfile changedirectory a = do
redir newh h = do
closeFd h
dupTo newh h
+ alreadyrunning = error "Daemon is already running."
out = exitImmediately ExitSuccess
-lockPidFile :: FilePath -> IO ()
-lockPidFile file = void $ do
+lockPidFile :: Bool -> IO () -> FilePath -> IO ()
+lockPidFile write onfailure file = do
fd <- openFd file ReadWrite (Just stdFileMode) defaultFileFlags
- catchIO
- (setLock fd (WriteLock, AbsoluteSeek, 0, 0))
- (const $ error "Daemon is already running.")
- fdWrite fd =<< show <$> getProcessID
+ when (write) $ void $
+ fdWrite fd =<< show <$> getProcessID
+ catchIO (setLock fd (locktype, AbsoluteSeek, 0, 0)) (const onfailure)
+ where
+ locktype
+ | write = WriteLock
+ | otherwise = ReadLock
+
+{- Stops the daemon.
+ -
+ - The pid file is used to get the daemon's pid.
+ -
+ - To guard against a stale pid, try to take a nonblocking shared lock
+ - of the pid file. If this *fails*, the daemon must be running,
+ - and have the exclusive lock, so the pid file is trustworthy.
+ -}
+stopDaemon :: FilePath -> IO ()
+stopDaemon pidfile = lockPidFile False go pidfile
+ where
+ go = do
+ pid <- readish <$> readFile pidfile
+ maybe noop (signalProcess sigTERM) pid
diff --git a/doc/git-annex.mdwn b/doc/git-annex.mdwn
index 8ff005d8d..39fad0488 100644
--- a/doc/git-annex.mdwn
+++ b/doc/git-annex.mdwn
@@ -177,7 +177,8 @@ subdirectories).
background, you no longer need to manually run git commands when
manipulating your files.
- To not daemonize, run with --foreground
+ To not daemonize, run with --foreground ; to stop a running daemon,
+ run with --stop
# REPOSITORY SETUP COMMANDS