module System.Unix.KillByCwd
( killByCwd
) where
import Control.Exception (catch)
import Control.Monad (liftM, filterM)
import Data.Char (isDigit)
import Data.List (isPrefixOf)
import Prelude hiding (catch)
import System.Directory (getDirectoryContents)
import System.Posix.Files (readSymbolicLink)
import System.Posix.Signals (signalProcess, sigTERM)
killByCwd :: FilePath -> IO [(String, Maybe String)]
killByCwd path =
do pids <- liftM (filter (all isDigit)) (getDirectoryContents "/proc")
cwdPids <- filterM (isCwd path) pids
exePaths <- mapM exePath cwdPids
mapM_ kill cwdPids
return (zip cwdPids exePaths)
where
isCwd :: FilePath -> String -> IO Bool
isCwd cwd pid =
(liftM (isPrefixOf cwd) (readSymbolicLink ("/proc/" ++ pid ++"/cwd"))) `catch` (\ (_ :: IOError) -> return False)
exePath :: String -> IO (Maybe String)
exePath pid = (readSymbolicLink ("/proc/" ++ pid ++"/exe") >>= return . Just) `catch` (\ (_ :: IOError) -> return Nothing)
kill :: String -> IO ()
kill pidStr = signalProcess sigTERM (read pidStr)