aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar simonmar <unknown>2003-03-26 12:35:34 +0000
committerGravatar simonmar <unknown>2003-03-26 12:35:34 +0000
commitb1a277421ab00dbd9b71702ddfbef1b62d46e0df (patch)
tree1e2b630baaec300dee70e75b225413cc39b83404
parented31973d867d76516d6a91e81d76286e6c77184c (diff)
[project @ 2003-03-26 12:35:34 by simonmar]
Add getrlimit()/setrlimit() suppport
-rw-r--r--System/Posix.hs5
-rw-r--r--System/Posix/Resource.hsc137
2 files changed, 141 insertions, 1 deletions
diff --git a/System/Posix.hs b/System/Posix.hs
index 85776d1..1e5cadf 100644
--- a/System/Posix.hs
+++ b/System/Posix.hs
@@ -24,6 +24,7 @@ module System.Posix (
module System.Posix.Terminal,
module System.Posix.Time,
module System.Posix.User,
+ module System.Posix.Resource
) where
import System.Posix.Types
@@ -37,6 +38,7 @@ import System.Posix.Env
import System.Posix.Terminal
import System.Posix.Time
import System.Posix.User
+import System.Posix.Resource
{- TODO
@@ -83,6 +85,7 @@ utime.h System.Posix.Files
pwd.h System.Posix.User
grp.h System.Posix.User
stdlib.h: System.Posix.Env (getenv()/setenv()/unsetenv())
+sys/resource.h: System.Posix.Resource (get/setrlimit() only)
network package:
@@ -98,7 +101,7 @@ To be supported
limits.h
poll.h
-sys/resource.h
+sys/resource.h (getrusage(): use instead of times() for getProcessTimes?)
sys/select.h
sys/statvfs.h (?)
sys/time.h (but maybe not the itimer?)
diff --git a/System/Posix/Resource.hsc b/System/Posix/Resource.hsc
new file mode 100644
index 0000000..0547436
--- /dev/null
+++ b/System/Posix/Resource.hsc
@@ -0,0 +1,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
+-}