module System.Linux.Process.CGroup.VFS(
CGroup(..),
allCGroups,
listTasks,
addTask) where
import Control.Monad(guard,mzero)
import System.IO (Handle, IOMode(..), hGetContents, openFile, withFile, hPutStr)
import System.FilePath.Posix
import Data.Monoid (mempty, Monoid(..))
import Data.Maybe(catMaybes)
import System.Posix.Types(ProcessID)
data CGroup = CheckedCGroup FilePath
| SystemCGroup FilePath
deriving (Eq, Show)
type CGroupType = String
filePathForCGroup :: CGroup -> FilePath
filePathForCGroup (CheckedCGroup g) = g
filePathForCGroup (SystemCGroup g) = g
writeLine :: FilePath -> String -> IO ()
writeLine name line = withFile name WriteMode (\h -> hPutStr h line >> hPutStr h "\n")
allCGroups :: Bool -> IO [CGroup]
allCGroups checked = fmap (map CheckedCGroup . catMaybes . map decodeLine . lines) (readFile "/proc/mounts")
where checker = if checked then CheckedCGroup else SystemCGroup
decodeLine l = case words l of
("cgroup":b:_) -> Just b
_ -> Nothing
checked :: Monoid a => CGroup -> (FilePath -> IO a) -> IO a
checked (SystemCGroup p) m = (m p)
checked g@(CheckedCGroup p) m = do allG <- allCGroups True
if g `elem` allG then m p else fail "cgroup does not exist"
listTasks :: CGroup -> IO [ProcessID]
listTasks g = checked g (\p -> fmap (map read . lines) (readFile (p </> "tasks")))
addTask :: CGroup -> ProcessID -> IO ()
addTask g p = checked g (\z -> writeLine (z </> "tasks") (show p))