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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
{-# OPTIONS -fffi #-}
-----------------------------------------------------------------------------
-- |
-- Module : System.Posix.Resource
-- Copyright : (c) The University of Glasgow 2003
-- License : BSD-style (see the file libraries/base/LICENSE)
--
-- Maintainer : libraries@haskell.org
-- Stability : provisional
-- Portability : non-portable (requires POSIX)
--
-- POSIX resource support
--
-----------------------------------------------------------------------------
module System.Posix.Resource (
-- * Resource Limits
ResourceLimit(..), ResourceLimits(..), Resource(..),
getResourceLimit,
setResourceLimit,
) where
#include "HsUnix.h"
import System.Posix.Types
import Foreign
import Foreign.C
-- -----------------------------------------------------------------------------
-- Resource limits
data Resource
= ResourceCoreFileSize
| ResourceCPUTime
| ResourceDataSize
| ResourceFileSize
| ResourceOpenFiles
| ResourceStackSize
| ResourceTotalMemory
deriving Eq
data ResourceLimits
= ResourceLimits { softLimit, hardLimit :: ResourceLimit }
deriving Eq
data ResourceLimit
= ResourceLimitInfinity
| ResourceLimitUnknown
| ResourceLimit Integer
deriving Eq
type RLimit = ()
foreign import ccall unsafe "getrlimit"
c_getrlimit :: CInt -> Ptr RLimit -> IO CInt
foreign import ccall unsafe "setrlimit"
c_setrlimit :: CInt -> Ptr RLimit -> IO CInt
getResourceLimit :: Resource -> IO ResourceLimits
getResourceLimit res = do
allocaBytes (#const sizeof(struct rlimit)) $ \p_rlimit -> do
throwErrnoIfMinus1 "getResourceLimit" $
c_getrlimit (packResource res) p_rlimit
soft <- (#peek struct rlimit, rlim_cur) p_rlimit
hard <- (#peek struct rlimit, rlim_max) p_rlimit
return (ResourceLimits {
softLimit = unpackRLimit soft,
hardLimit = unpackRLimit hard
})
setResourceLimit :: Resource -> ResourceLimits -> IO ()
setResourceLimit res ResourceLimits{softLimit=soft,hardLimit=hard} = do
allocaBytes (#const sizeof(struct rlimit)) $ \p_rlimit -> do
(#poke struct rlimit, rlim_cur) p_rlimit (packRLimit soft True)
(#poke struct rlimit, rlim_max) p_rlimit (packRLimit hard False)
throwErrnoIfMinus1 "setResourceLimit" $
c_setrlimit (packResource res) p_rlimit
return ()
packResource :: Resource -> CInt
packResource ResourceCoreFileSize = (#const RLIMIT_CORE)
packResource ResourceCPUTime = (#const RLIMIT_CPU)
packResource ResourceDataSize = (#const RLIMIT_DATA)
packResource ResourceFileSize = (#const RLIMIT_FSIZE)
packResource ResourceOpenFiles = (#const RLIMIT_NOFILE)
packResource ResourceStackSize = (#const RLIMIT_STACK)
packResource ResourceTotalMemory = (#const RLIMIT_AS)
unpackRLimit :: CRLim -> ResourceLimit
unpackRLimit (#const RLIM_INFINITY) = ResourceLimitInfinity
unpackRLimit (#const RLIM_SAVED_MAX) = ResourceLimitUnknown
unpackRLimit (#const RLIM_SAVED_CUR) = ResourceLimitUnknown
unpackRLimit other = ResourceLimit (fromIntegral other)
packRLimit :: ResourceLimit -> Bool -> CRLim
packRLimit ResourceLimitInfinity _ = (#const RLIM_INFINITY)
packRLimit ResourceLimitUnknown True = (#const RLIM_SAVED_CUR)
packRLimit ResourceLimitUnknown False = (#const RLIM_SAVED_MAX)
packRLimit (ResourceLimit other) _ = fromIntegral other
-- -----------------------------------------------------------------------------
-- Test code
{-
import System.Posix
import Control.Monad
main = do
zipWithM_ (\r n -> setResourceLimit r ResourceLimits{
hardLimit = ResourceLimit n,
softLimit = ResourceLimit n })
allResources [1..]
showAll
mapM_ (\r -> setResourceLimit r ResourceLimits{
hardLimit = ResourceLimit 1,
softLimit = ResourceLimitInfinity })
allResources
-- should fail
showAll =
mapM_ (\r -> getResourceLimit r >>= (putStrLn . showRLims)) allResources
allResources =
[ResourceCoreFileSize, ResourceCPUTime, ResourceDataSize,
ResourceFileSize, ResourceOpenFiles, ResourceStackSize,
ResourceTotalMemory ]
showRLims ResourceLimits{hardLimit=h,softLimit=s}
= "hard: " ++ showRLim h ++ ", soft: " ++ showRLim s
showRLim ResourceLimitInfinity = "infinity"
showRLim ResourceLimitUnknown = "unknown"
showRLim (ResourceLimit other) = show other
-}
|