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

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

    {-# 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

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

    {-# LINE 40 "libraries/unix/System/Posix/Resource.hsc" #-}
    import GHC.Exts ( considerAccessible )

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

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

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

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

    {-# LINE 56 "libraries/unix/System/Posix/Resource.hsc" #-}
      deriving (Eq, Show)

    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
    $c== :: ResourceLimits -> ResourceLimits -> Bool
    == :: ResourceLimits -> ResourceLimits -> Bool
    $c/= :: ResourceLimits -> ResourceLimits -> Bool
    /= :: ResourceLimits -> ResourceLimits -> Bool
    Eq, Int -> ResourceLimits -> ShowS
    [ResourceLimits] -> ShowS
    ResourceLimits -> String
    (Int -> ResourceLimits -> ShowS)
    -> (ResourceLimits -> String)
    -> ([ResourceLimits] -> ShowS)
    -> Show ResourceLimits
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> ResourceLimits -> ShowS
    showsPrec :: Int -> ResourceLimits -> ShowS
    $cshow :: ResourceLimits -> String
    show :: ResourceLimits -> String
    $cshowList :: [ResourceLimits] -> ShowS
    showList :: [ResourceLimits] -> ShowS
    Show)

    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
    $c== :: ResourceLimit -> ResourceLimit -> Bool
    == :: ResourceLimit -> ResourceLimit -> Bool
    $c/= :: ResourceLimit -> ResourceLimit -> Bool
    /= :: ResourceLimit -> ResourceLimit -> Bool
    Eq, Int -> ResourceLimit -> ShowS
    [ResourceLimit] -> ShowS
    ResourceLimit -> String
    (Int -> ResourceLimit -> ShowS)
    -> (ResourceLimit -> String)
    -> ([ResourceLimit] -> ShowS)
    -> Show ResourceLimit
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> ResourceLimit -> ShowS
    showsPrec :: Int -> ResourceLimit -> ShowS
    $cshow :: ResourceLimit -> String
    show :: ResourceLimit -> String
    $cshowList :: [ResourceLimit] -> ShowS
    showList :: [ResourceLimit] -> ShowS
    Show)

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

    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 93 "libraries/unix/System/Posix/Resource.hsc" #-}
        throwErrnoIfMinus1_ "getResourceLimit" $
          c_getrlimit (packResource res) p_rlimit
        soft <- ((\hsc_ptr -> peekByteOff hsc_ptr 0)) p_rlimit
    {-# LINE 96 "libraries/unix/System/Posix/Resource.hsc" #-}
        hard <- ((\hsc_ptr -> peekByteOff hsc_ptr 8)) p_rlimit
    {-# LINE 97 "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 105 "libraries/unix/System/Posix/Resource.hsc" #-}
        ((\hsc_ptr -> pokeByteOff hsc_ptr 0)) p_rlimit (packRLimit soft True)
    {-# LINE 106 "libraries/unix/System/Posix/Resource.hsc" #-}
        ((\hsc_ptr -> pokeByteOff hsc_ptr 8)) p_rlimit (packRLimit hard False)
    {-# LINE 107 "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 113 "libraries/unix/System/Posix/Resource.hsc" #-}
    packResource ResourceCPUTime       = (0)
    {-# LINE 114 "libraries/unix/System/Posix/Resource.hsc" #-}
    packResource ResourceDataSize      = (2)
    {-# LINE 115 "libraries/unix/System/Posix/Resource.hsc" #-}
    packResource ResourceFileSize      = (1)
    {-# LINE 116 "libraries/unix/System/Posix/Resource.hsc" #-}
    packResource ResourceOpenFiles     = (7)
    {-# LINE 117 "libraries/unix/System/Posix/Resource.hsc" #-}
    packResource ResourceStackSize     = (3)
    {-# LINE 118 "libraries/unix/System/Posix/Resource.hsc" #-}

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

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

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

    {-# LINE 126 "libraries/unix/System/Posix/Resource.hsc" #-}
        | ((18446744073709551615) :: CRLim) /= (18446744073709551615)
    {-# LINE 127 "libraries/unix/System/Posix/Resource.hsc" #-}
        , other == (18446744073709551615)
    {-# LINE 128 "libraries/unix/System/Posix/Resource.hsc" #-}
        = ResourceLimitUnknown

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

    {-# LINE 131 "libraries/unix/System/Posix/Resource.hsc" #-}
        | ((18446744073709551615) :: CRLim) /= (18446744073709551615)
    {-# LINE 132 "libraries/unix/System/Posix/Resource.hsc" #-}
        , other == (18446744073709551615)
    {-# LINE 133 "libraries/unix/System/Posix/Resource.hsc" #-}

    {-# LINE 134 "libraries/unix/System/Posix/Resource.hsc" #-}
        , considerAccessible

    {-# LINE 136 "libraries/unix/System/Posix/Resource.hsc" #-}
        = ResourceLimitUnknown
        -- (*) This pattern match is redundant if RLIM_SAVED_MAX and RLIM_SAVED_CUR
        -- are both defined and are equal. This redundancy is only detected by GHC
        -- starting from version 9.5, so we use 'considerAccessible'.

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

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

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

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

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

    {-# LINE 157 "libraries/unix/System/Posix/Resource.hsc" #-}
    packRLimit (ResourceLimit Integer
    other) Bool
    _     = Integer -> CRLim
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Integer
    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
    -}

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