{-# LINE 1 "libraries/unix/System/Posix/Resource.hsc" #-}
{-# LANGUAGE CApiFFI #-}

{-# LINE 3 "libraries/unix/System/Posix/Resource.hsc" #-}
{-# LANGUAGE Safe #-}

{-# LINE 7 "libraries/unix/System/Posix/Resource.hsc" #-}
-----------------------------------------------------------------------------
-- |
-- 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



import System.Posix.Types
import Foreign
import Foreign.C

-- -----------------------------------------------------------------------------
-- Resource limits

data Resource
  = ResourceCoreFileSize
  | ResourceCPUTime
  | ResourceDataSize
  | ResourceFileSize
  | ResourceOpenFiles
  | ResourceStackSize

{-# LINE 45 "libraries/unix/System/Posix/Resource.hsc" #-}
  | ResourceTotalMemory

{-# LINE 47 "libraries/unix/System/Posix/Resource.hsc" #-}
  deriving Eq

data ResourceLimits
  = ResourceLimits { ResourceLimits -> ResourceLimit
softLimit, ResourceLimits -> ResourceLimit
hardLimit :: ResourceLimit }
  deriving ResourceLimits -> ResourceLimits -> Bool
(ResourceLimits -> ResourceLimits -> Bool)
-> (ResourceLimits -> ResourceLimits -> Bool) -> Eq ResourceLimits
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ResourceLimits -> ResourceLimits -> Bool
$c/= :: ResourceLimits -> ResourceLimits -> Bool
== :: ResourceLimits -> ResourceLimits -> Bool
$c== :: ResourceLimits -> ResourceLimits -> Bool
Eq

data ResourceLimit
  = ResourceLimitInfinity
  | ResourceLimitUnknown
  | ResourceLimit Integer
  deriving ResourceLimit -> ResourceLimit -> Bool
(ResourceLimit -> ResourceLimit -> Bool)
-> (ResourceLimit -> ResourceLimit -> Bool) -> Eq ResourceLimit
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ResourceLimit -> ResourceLimit -> Bool
$c/= :: ResourceLimit -> ResourceLimit -> Bool
== :: ResourceLimit -> ResourceLimit -> Bool
$c== :: ResourceLimit -> ResourceLimit -> Bool
Eq

data {-# CTYPE "struct rlimit" #-} RLimit

foreign import capi unsafe "HsUnix.h getrlimit"
  c_getrlimit :: CInt -> Ptr RLimit -> IO CInt

foreign import capi unsafe "HsUnix.h setrlimit"
  c_setrlimit :: CInt -> Ptr RLimit -> IO CInt

getResourceLimit :: Resource -> IO ResourceLimits
getResourceLimit :: Resource -> IO ResourceLimits
getResourceLimit Resource
res = do
  Int -> (Ptr RLimit -> IO ResourceLimits) -> IO ResourceLimits
forall a b. Int -> (Ptr a -> IO b) -> IO b
allocaBytes (Int
16) ((Ptr RLimit -> IO ResourceLimits) -> IO ResourceLimits)
-> (Ptr RLimit -> IO ResourceLimits) -> IO ResourceLimits
forall a b. (a -> b) -> a -> b
$ \Ptr RLimit
p_rlimit -> do
{-# LINE 70 "libraries/unix/System/Posix/Resource.hsc" #-}
    throwErrnoIfMinus1_ "getResourceLimit" $
      c_getrlimit (packResource res) p_rlimit
    soft <- ((\hsc_ptr -> peekByteOff hsc_ptr 0)) p_rlimit
{-# LINE 73 "libraries/unix/System/Posix/Resource.hsc" #-}
    hard <- ((\hsc_ptr -> peekByteOff hsc_ptr 8)) p_rlimit
{-# LINE 74 "libraries/unix/System/Posix/Resource.hsc" #-}
    return (ResourceLimits {
                softLimit = unpackRLimit soft,
                hardLimit = unpackRLimit hard
           })

setResourceLimit :: Resource -> ResourceLimits -> IO ()
setResourceLimit :: Resource -> ResourceLimits -> IO ()
setResourceLimit Resource
res ResourceLimits{softLimit :: ResourceLimits -> ResourceLimit
softLimit=ResourceLimit
soft,hardLimit :: ResourceLimits -> ResourceLimit
hardLimit=ResourceLimit
hard} = do
  Int -> (Ptr RLimit -> IO ()) -> IO ()
forall a b. Int -> (Ptr a -> IO b) -> IO b
allocaBytes (Int
16) ((Ptr RLimit -> IO ()) -> IO ()) -> (Ptr RLimit -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr RLimit
p_rlimit -> do
{-# LINE 82 "libraries/unix/System/Posix/Resource.hsc" #-}
    ((\hsc_ptr -> pokeByteOff hsc_ptr 0)) p_rlimit (packRLimit soft True)
{-# LINE 83 "libraries/unix/System/Posix/Resource.hsc" #-}
    ((\hsc_ptr -> pokeByteOff hsc_ptr 8)) p_rlimit (packRLimit hard False)
{-# LINE 84 "libraries/unix/System/Posix/Resource.hsc" #-}
    throwErrnoIfMinus1_ "setResourceLimit" $
        c_setrlimit (packResource res) p_rlimit
    return ()

packResource :: Resource -> CInt
packResource :: Resource -> CInt
packResource Resource
ResourceCoreFileSize  = (CInt
4)
{-# LINE 90 "libraries/unix/System/Posix/Resource.hsc" #-}
packResource ResourceCPUTime       = (0)
{-# LINE 91 "libraries/unix/System/Posix/Resource.hsc" #-}
packResource ResourceDataSize      = (2)
{-# LINE 92 "libraries/unix/System/Posix/Resource.hsc" #-}
packResource ResourceFileSize      = (1)
{-# LINE 93 "libraries/unix/System/Posix/Resource.hsc" #-}
packResource ResourceOpenFiles     = (7)
{-# LINE 94 "libraries/unix/System/Posix/Resource.hsc" #-}
packResource ResourceStackSize     = (3)
{-# LINE 95 "libraries/unix/System/Posix/Resource.hsc" #-}

{-# LINE 96 "libraries/unix/System/Posix/Resource.hsc" #-}
packResource ResourceTotalMemory   = (9)
{-# LINE 97 "libraries/unix/System/Posix/Resource.hsc" #-}

{-# LINE 98 "libraries/unix/System/Posix/Resource.hsc" #-}

unpackRLimit :: CRLim -> ResourceLimit
unpackRLimit :: CRLim -> ResourceLimit
unpackRLimit (CRLim
18446744073709551615)  = ResourceLimit
ResourceLimitInfinity
{-# LINE 101 "libraries/unix/System/Posix/Resource.hsc" #-}
unpackRLimit other

{-# LINE 103 "libraries/unix/System/Posix/Resource.hsc" #-}
    | ((18446744073709551615) :: CRLim) /= (18446744073709551615) &&
{-# LINE 104 "libraries/unix/System/Posix/Resource.hsc" #-}
      other == (18446744073709551615) = ResourceLimitUnknown
{-# LINE 105 "libraries/unix/System/Posix/Resource.hsc" #-}

{-# LINE 106 "libraries/unix/System/Posix/Resource.hsc" #-}

{-# LINE 107 "libraries/unix/System/Posix/Resource.hsc" #-}
    | ((18446744073709551615) :: CRLim) /= (18446744073709551615) &&
{-# LINE 108 "libraries/unix/System/Posix/Resource.hsc" #-}
      other == (18446744073709551615) = ResourceLimitUnknown
{-# LINE 109 "libraries/unix/System/Posix/Resource.hsc" #-}

{-# LINE 110 "libraries/unix/System/Posix/Resource.hsc" #-}
    | otherwise = ResourceLimit (fromIntegral other)

packRLimit :: ResourceLimit -> Bool -> CRLim
packRLimit :: ResourceLimit -> Bool -> CRLim
packRLimit ResourceLimit
ResourceLimitInfinity Bool
_     = (CRLim
18446744073709551615)
{-# LINE 114 "libraries/unix/System/Posix/Resource.hsc" #-}

{-# LINE 115 "libraries/unix/System/Posix/Resource.hsc" #-}
packRLimit ResourceLimitUnknown  True  = (18446744073709551615)
{-# LINE 116 "libraries/unix/System/Posix/Resource.hsc" #-}

{-# LINE 117 "libraries/unix/System/Posix/Resource.hsc" #-}

{-# LINE 118 "libraries/unix/System/Posix/Resource.hsc" #-}
packRLimit ResourceLimitUnknown  False = (18446744073709551615)
{-# LINE 119 "libraries/unix/System/Posix/Resource.hsc" #-}

{-# LINE 120 "libraries/unix/System/Posix/Resource.hsc" #-}
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
#ifdef RLIMIT_AS
        , ResourceTotalMemory
#endif
        ]

showRLims ResourceLimits{hardLimit=h,softLimit=s}
  = "hard: " ++ showRLim h ++ ", soft: " ++ showRLim s

showRLim ResourceLimitInfinity = "infinity"
showRLim ResourceLimitUnknown  = "unknown"
showRLim (ResourceLimit other)  = show other
-}