summaryrefslogtreecommitdiffstats
path: root/CGroup/Types.hs
blob: 53ff4fad1436179bc6d7f10daaded77b220ac1ed (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
-- |
-- Module:      CGroup.Types
-- Copyright:   (c) 2014 Tomislav Viljetić
-- License:     BSD3
-- Maintainer:  Tomislav Viljetić <tomislav@viljetic.de>
--

module CGroup.Types
    ( CGroup
    , cgroup
    , cgroupPath
    , ProcessID
    ) where

import Data.Monoid
import qualified System.FilePath as FP


-- | A 'CGroup' is defined by a mount point and a cgroup name.
--
-- The mount point specifies where the cgroup hierarchy is mounted.
-- The cgroup name is a 'FilePath' relative to the mount point.
data CGroup = CGroup { mountPoint, cgroupName :: FilePath }
  deriving Show


-- | @'cgroup' mountPoint cgroupName@ is a smart constructor for 'CGroup'.
--
-- It will return 'Nothing' if @cgroupName@ could point outside
-- @mountPoint@ in order to prevent directory traversal attacks.
cgroup :: FilePath -> FilePath -> Maybe CGroup
cgroup mp0 cgn0
    | ".." `elem` parts = Nothing
    | FP.isAbsolute cgn = Nothing
    | otherwise = Just CGroup { mountPoint = mp, cgroupName = cgn }
  where
    mp = normaliseMountPoint mp0
    cgn = normaliseCGroupName cgn0
    parts = FP.splitDirectories cgn
    normaliseMountPoint = FP.addTrailingPathSeparator . FP.normalise
    normaliseCGroupName = FP.dropTrailingPathSeparator . FP.normalise


-- | @'cgroupPath' g@ returns the absolute 'FilePath' of cgroup @g@.
cgroupPath :: CGroup -> FilePath
cgroupPath CGroup { mountPoint = mp, cgroupName = cgn } =
    mp <> cgn


-- | A 'ProcessID' defines a task / process.
type ProcessID = Int