diff options
author | simonmar <unknown> | 2003-03-26 12:35:34 +0000 |
---|---|---|
committer | simonmar <unknown> | 2003-03-26 12:35:34 +0000 |
commit | b1a277421ab00dbd9b71702ddfbef1b62d46e0df (patch) | |
tree | 1e2b630baaec300dee70e75b225413cc39b83404 | |
parent | ed31973d867d76516d6a91e81d76286e6c77184c (diff) |
[project @ 2003-03-26 12:35:34 by simonmar]
Add getrlimit()/setrlimit() suppport
-rw-r--r-- | System/Posix.hs | 5 | ||||
-rw-r--r-- | System/Posix/Resource.hsc | 137 |
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 +-} |