    {-# LINE 1 "libraries/unix/System/Posix/Fcntl.hsc" #-}
    {-# LANGUAGE CApiFFI #-}
    {-# LANGUAGE Safe #-}
    -----------------------------------------------------------------------------
    -- |
    -- Module      :  System.Posix.Fcntl
    -- Copyright   :  (c) The University of Glasgow 2014
    -- License     :  BSD-style (see the file LICENSE)
    --
    -- Maintainer  :  libraries@haskell.org
    -- Stability   :  provisional
    -- Portability :  non-portable (requires POSIX)
    --
    -- POSIX file control support
    --
    -- @since 2.7.1.0
    -----------------------------------------------------------------------------

    module System.Posix.Fcntl (
        -- * File allocation
        Advice(..), fileAdvise,
        fileAllocate,
        -- * File caching
        fileGetCaching,
        fileSetCaching,
      ) where

    import Foreign.C
    import System.Posix.Types

    {-# LINE 37 "libraries/unix/System/Posix/Fcntl.hsc" #-}

    {-# LINE 39 "libraries/unix/System/Posix/Fcntl.hsc" #-}
    import Data.Bits (complement, (.&.), (.|.))
    import System.Posix.Internals (c_fcntl_read)

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

    {-# LINE 44 "libraries/unix/System/Posix/Fcntl.hsc" #-}
    import System.Posix.Internals (c_fcntl_write)

    {-# LINE 46 "libraries/unix/System/Posix/Fcntl.hsc" #-}

    -- -----------------------------------------------------------------------------
    -- File control

    -- | Advice parameter for 'fileAdvise' operation.
    --
    -- For more details, see documentation of @posix_fadvise(2)@.
    --
    -- @since 2.7.1.0
    data Advice
      = AdviceNormal
      | AdviceRandom
      | AdviceSequential
      | AdviceWillNeed
      | AdviceDontNeed
      | AdviceNoReuse
      deriving Advice -> Advice -> Bool
    (Advice -> Advice -> Bool)
    -> (Advice -> Advice -> Bool) -> Eq Advice
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Advice -> Advice -> Bool
    == :: Advice -> Advice -> Bool
    $c/= :: Advice -> Advice -> Bool
    /= :: Advice -> Advice -> Bool
    Eq

    -- | Performs @posix_fadvise(2)@ operation on file-descriptor.
    --
    -- If platform does not provide @posix_fadvise(2)@ 'fileAdvise'
    -- becomes a no-op.
    --
    -- (use @#if HAVE_POSIX_FADVISE@ CPP guard to detect availability)
    --
    -- @since 2.7.1.0
    fileAdvise :: Fd -> FileOffset -> FileOffset -> Advice -> IO ()

    {-# LINE 74 "libraries/unix/System/Posix/Fcntl.hsc" #-}
    fileAdvise fd off len adv = do
      throwErrnoIfMinus1_ "fileAdvise" (c_posix_fadvise (fromIntegral fd) (fromIntegral off) (fromIntegral len) (packAdvice adv))

    foreign import capi safe "fcntl.h posix_fadvise"
      c_posix_fadvise :: CInt -> COff -> COff -> CInt -> IO CInt

    packAdvice :: Advice -> CInt
    packAdvice :: Advice -> CInt
    packAdvice Advice
    AdviceNormal     = (CInt
    0)
    {-# LINE 82 "libraries/unix/System/Posix/Fcntl.hsc" #-}
    packAdvice AdviceRandom     = (1)
    {-# LINE 83 "libraries/unix/System/Posix/Fcntl.hsc" #-}
    packAdvice AdviceSequential = (2)
    {-# LINE 84 "libraries/unix/System/Posix/Fcntl.hsc" #-}
    packAdvice AdviceWillNeed   = (3)
    {-# LINE 85 "libraries/unix/System/Posix/Fcntl.hsc" #-}
    packAdvice AdviceDontNeed   = (4)
    {-# LINE 86 "libraries/unix/System/Posix/Fcntl.hsc" #-}
    packAdvice AdviceNoReuse    = (5)
    {-# LINE 87 "libraries/unix/System/Posix/Fcntl.hsc" #-}

    {-# LINE 90 "libraries/unix/System/Posix/Fcntl.hsc" #-}

    -- | Performs @posix_fallocate(2)@ operation on file-descriptor.
    --
    -- Throws 'IOError' (\"unsupported operation\") if platform does not
    -- provide @posix_fallocate(2)@.
    --
    -- (use @#if HAVE_POSIX_FALLOCATE@ CPP guard to detect availability).
    --
    -- @since 2.7.1.0
    fileAllocate :: Fd -> FileOffset -> FileOffset -> IO ()

    {-# LINE 101 "libraries/unix/System/Posix/Fcntl.hsc" #-}
    fileAllocate fd off len = do
      ret <- c_posix_fallocate (fromIntegral fd) (fromIntegral off) (fromIntegral len)
      if ret == 0
        then pure ()
        else ioError (errnoToIOError "fileAllocate" (Errno ret) Nothing Nothing)

    foreign import capi safe "fcntl.h posix_fallocate"
      c_posix_fallocate :: CInt -> COff -> COff -> IO CInt

    {-# LINE 115 "libraries/unix/System/Posix/Fcntl.hsc" #-}

    -- -----------------------------------------------------------------------------
    -- File caching

    -- | Performs the @fcntl(2)@ operation on a file-desciptor to get the cache mode.
    --
    -- If the cache mode is 'False', then cache effects for file system reads and
    -- writes are minimised or otherwise eliminated. If the cache mode is 'True',
    -- then cache effects occur like normal.
    --
    -- On Linux, FreeBSD, and NetBSD this checks whether the @O_DIRECT@ file flag is
    -- set.
    --
    -- Throws 'IOError' (\"unsupported operation\") if platform does not support
    -- getting the cache mode.
    --
    -- Use @#if HAVE_O_DIRECT@ CPP guard to detect availability. Use @#include
    -- "HsUnix.h"@ to bring @HAVE_O_DIRECT@ into scope.
    --
    -- @since 2.8.7.0
    fileGetCaching :: Fd -> IO Bool

    {-# LINE 137 "libraries/unix/System/Posix/Fcntl.hsc" #-}
    fileGetCaching (Fd fd) = do
        r <- throwErrnoIfMinus1 "fileGetCaching" (c_fcntl_read fd 3)
    {-# LINE 139 "libraries/unix/System/Posix/Fcntl.hsc" #-}
        return ((r .&. opt_val) == 0)
      where
        opt_val = 16384
    {-# LINE 142 "libraries/unix/System/Posix/Fcntl.hsc" #-}

    {-# LINE 147 "libraries/unix/System/Posix/Fcntl.hsc" #-}

    -- | Performs the @fcntl(2)@ operation on a file-desciptor to set the cache
    -- mode.
    --
    -- If the cache mode is 'False', then cache effects for file system reads and
    -- writes are minimised or otherwise eliminated. If the cache mode is 'True',
    -- then cache effects occur like normal.
    --
    -- On Linux, FreeBSD, and NetBSD this sets the @O_DIRECT@ file flag. On OSX,
    -- this sets the @F_NOCACHE@ @fcntl@ flag.
    --
    -- Throws 'IOError' (\"unsupported operation\") if platform does not support
    -- setting the cache mode.
    --
    -- Use @#if HAVE_O_DIRECT || HAVE_F_NOCACHE@ CPP guard to detect availability.
    -- Use @#include "HsUnix.h"@ to bring @HAVE_O_DIRECT@ and @HAVE_F_NOCACHE@ into
    -- scope.
    --
    -- @since 2.8.7.0
    fileSetCaching :: Fd -> Bool -> IO ()

    {-# LINE 168 "libraries/unix/System/Posix/Fcntl.hsc" #-}
    fileSetCaching (Fd fd) val = do
        r <- throwErrnoIfMinus1 "fileSetCaching" (c_fcntl_read fd 3)
    {-# LINE 170 "libraries/unix/System/Posix/Fcntl.hsc" #-}
        let r' | val       = fromIntegral r .&. complement opt_val
               | otherwise = fromIntegral r .|. opt_val
        throwErrnoIfMinus1_ "fileSetCaching" (c_fcntl_write fd 4 r')
    {-# LINE 173 "libraries/unix/System/Posix/Fcntl.hsc" #-}
      where
        opt_val = 16384
    {-# LINE 175 "libraries/unix/System/Posix/Fcntl.hsc" #-}

    {-# LINE 183 "libraries/unix/System/Posix/Fcntl.hsc" #-}