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
|