{-# LINE 1 "src/System/Posix/FileControl.hsc" #-}
{-# LANGUAGE GADTs #-}
{-# LINE 2 "src/System/Posix/FileControl.hsc" #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE ViewPatterns #-}
module System.Posix.FileControl
  ( fcntl
  , Fcntl(..)

  -- * File descriptor flags
  , FileDescriptorFlags
  , pattern FD_CLOEXEC

  -- * File status flags
  , FileStatusFlags
  , pattern O_RDONLY
  , pattern O_WRONLY
  , pattern O_RDWR
  , pattern O_ACCMODE
  , pattern O_CREAT
  , pattern O_EXCL
  , pattern O_NONBLOCK
  , pattern O_NOCTTY
  , pattern O_TRUNC
  , pattern O_APPEND
  , pattern O_NDELAY

  -- * Advisory and mandatory locking
  , Flock
  , newFlock
  , flockType
  , FlockType
  , pattern F_RDLCK
  , pattern F_WRLCK
  , pattern F_UNLCK
  , flockWhence
  , FlockWhence
  , pattern SEEK_SET
  , pattern SEEK_CUR
  , pattern SEEK_END
  , flockStart
  , flockLen
  , flockPid



{-# LINE 64 "src/System/Posix/FileControl.hsc" #-}


{-# LINE 73 "src/System/Posix/FileControl.hsc" #-}
  ) where
import Control.Applicative
import Foreign
import Foreign.C
import System.Posix.Types
import Prelude

import Foreign.Var hiding (get)


{-# LINE 85 "src/System/Posix/FileControl.hsc" #-}


{-# LINE 87 "src/System/Posix/FileControl.hsc" #-}

{-# LINE 88 "src/System/Posix/FileControl.hsc" #-}

{-# LINE 89 "src/System/Posix/FileControl.hsc" #-}

-- | Perform one of the operations in 'Fcntl'
fcntl :: Fd -> Fcntl a -> IO a
fcntl fd cmd = case cmd of
  -- Duplicating a file descriptor
  F_DUPFD minFd ->
    fcntl_set_int fd (0) minFd
{-# LINE 96 "src/System/Posix/FileControl.hsc" #-}
  F_DUPFD_CLOEXEC minFd ->
    fcntl_set_int fd (1030) minFd
{-# LINE 98 "src/System/Posix/FileControl.hsc" #-}

  -- File descriptor flags
  F_GETFD ->
    FileDescriptorFlags <$> fcntl_get_int fd (1)
{-# LINE 102 "src/System/Posix/FileControl.hsc" #-}
  F_SETFD (FileDescriptorFlags flags) ->
    fcntl_set_int_ fd (2) flags
{-# LINE 104 "src/System/Posix/FileControl.hsc" #-}

  -- File status flags
  F_GETFL ->
    FileStatusFlags <$> fcntl_get_int fd (3)
{-# LINE 108 "src/System/Posix/FileControl.hsc" #-}
  F_SETFL (FileStatusFlags flags) ->
    fcntl_set_int_ fd (4) flags
{-# LINE 110 "src/System/Posix/FileControl.hsc" #-}

  -- Advisory or mandatory locking
  F_GETLK ->
    fcntl_get_flock fd (5)
{-# LINE 114 "src/System/Posix/FileControl.hsc" #-}
  F_SETLK flock ->
    fcntl_set_flock fd (6) flock
{-# LINE 116 "src/System/Posix/FileControl.hsc" #-}
  F_SETLKW flock ->
    fcntl_set_flock fd (7) flock
{-# LINE 118 "src/System/Posix/FileControl.hsc" #-}


{-# LINE 128 "src/System/Posix/FileControl.hsc" #-}

  -- Managing signals
  F_GETOWN ->
    fcntl_get_int fd (9)
{-# LINE 132 "src/System/Posix/FileControl.hsc" #-}
  F_SETOWN pid ->
    fcntl_set_int_ fd (4) pid
{-# LINE 134 "src/System/Posix/FileControl.hsc" #-}

{-# LINE 160 "src/System/Posix/FileControl.hsc" #-}


{-# LINE 168 "src/System/Posix/FileControl.hsc" #-}

-- | Type of operations which 'fcntl' can perform. Available operations vary
-- depending on platforms. Please consult manpage on your platform for details.
--
-- All possible operations are:
--
-- * Duplicating a file descriptor
--
--     * 'F_DUPFD'
--     * 'F_DUPFD_CLOEXEC'
--
-- * File descriptor flags
--
--     * 'F_GETFD':
--     * 'F_SETFD'
--
-- * File status flags
--
--    * 'F_GETFL'
--    * 'F_SETFL'
--
-- * Advisory or mandatory locking
--
--    * 'F_GETLK'
--    * 'F_SETLK'
--    * 'F_SETLKW'
--
-- * Open file description locks (Linux 3.15 or later).
--
--    @-fgnu@ flag needs to be enabled to use this feature.
--
--    * 'F_OFD_GETLK'
--    * 'F_OFD_SETLK'
--    * 'F_OFD_SETLKW'
--
-- * Managing signals
--
--    * 'F_GETOWN'
--    * 'F_SETOWN'
--    * 'F_GETOWN_EX'
--    * 'F_SETOWN_EX'
--    * 'F_GETSIG'
--    * 'F_SETSIG'
--
-- * Leases
--
--    * 'F_GETLEASE'
--    * 'F_SETLEASE'
--
-- * File and directory change notification (dnotify; Linux 2.4 or later)
--
--    * 'F_NOTIFY'
--
-- * Changing the capacity of a pipe
--
--    * 'F_GETPIPE_SZ'
--    * 'F_SETPIPE_SZ'
--
-- * File leasing
--
--    * 'F_GET_SEALS'
--    * 'F_ADD_SEALS'
data Fcntl a where
  -- Duplicating a file descriptor
  F_DUPFD :: Fd -> Fcntl Fd
  F_DUPFD_CLOEXEC :: Fd -> Fcntl Fd

  -- File descriptor flags
  F_GETFD :: Fcntl FileDescriptorFlags
  F_SETFD :: FileDescriptorFlags -> Fcntl ()

  -- File status flags
  F_GETFL :: Fcntl FileStatusFlags
  F_SETFL :: FileStatusFlags -> Fcntl ()

  -- Advisory or mandatory locking
  F_GETLK :: Fcntl Flock
  F_SETLK :: Flock -> Fcntl ()
  F_SETLKW :: Flock -> Fcntl ()


{-# LINE 254 "src/System/Posix/FileControl.hsc" #-}

  -- Managing signals
  F_GETOWN :: Fcntl ProcessID
  F_SETOWN :: ProcessID -> Fcntl ()


{-# LINE 279 "src/System/Posix/FileControl.hsc" #-}


{-# LINE 285 "src/System/Posix/FileControl.hsc" #-}

-- Helper functions

fcntl_get_int :: Integral a => Fd -> CInt -> IO a
fcntl_get_int fd cmd =
  fromIntegral <$> throwErrnoIfMinus1 "fcntl"
    (c_fcntl_get_int (fromIntegral fd) cmd)

foreign import ccall safe "fcntl"
  c_fcntl_get_int :: CInt -> CInt -> IO CInt

fcntl_set_int :: (Integral a, Integral b) => Fd -> CInt -> a -> IO b
fcntl_set_int fd cmd n =
  fromIntegral <$> throwErrnoIfMinus1 "fcntl"
    (c_fcntl_set_int (fromIntegral fd) cmd (fromIntegral n))

fcntl_set_int_ :: Integral a => Fd -> CInt -> a -> IO ()
fcntl_set_int_ fd cmd n =
  throwErrnoIfMinus1_ "fcntl"
    (c_fcntl_set_int (fromIntegral fd) cmd (fromIntegral n))

foreign import ccall safe "fcntl"
  c_fcntl_set_int :: CInt -> CInt -> CInt -> IO CInt

fcntl_get_flock :: Fd -> CInt -> IO Flock
fcntl_get_flock fd cmd = do
  flock <- newFlock
  throwErrnoIfMinus1_ "fcntl" $
    withFlock flock $ c_fcntl_get_flock (fromIntegral fd) cmd
  return flock

foreign import ccall safe "fcntl"
  c_fcntl_get_flock :: CInt -> CInt -> Ptr Flock -> IO CInt

fcntl_set_flock :: Fd -> CInt -> Flock -> IO ()
fcntl_set_flock fd cmd flock =
  throwErrnoIfMinus1_ "fcntl" $
    withFlock flock $ c_fcntl_set_flock (fromIntegral fd) cmd

foreign import ccall safe "fcntl"
  c_fcntl_set_flock :: CInt -> CInt -> Ptr Flock -> IO CInt


{-# LINE 348 "src/System/Posix/FileControl.hsc" #-}

-----------------------------------------------------------
-- File descriptor flags

newtype FileDescriptorFlags = FileDescriptorFlags CInt

pattern FD_CLOEXEC :: FileDescriptorFlags
pattern FD_CLOEXEC = FileDescriptorFlags 4207876
{-# LINE 355 "src/System/Posix/FileControl.hsc" #-}

-----------------------------------------------------------
-- File status flags

newtype FileStatusFlags = FileStatusFlags CInt

-- File access modes
pattern O_RDONLY :: FileStatusFlags
pattern O_RDONLY <- ((\(FileStatusFlags n) -> n .&. _O_RDONLY > 0) -> True)
  where
    O_RDONLY = FileStatusFlags _O_RDONLY
_O_RDONLY :: CInt
_O_RDONLY = 4208081
{-# LINE 363 "src/System/Posix/FileControl.hsc" #-}
pattern O_WRONLY :: FileStatusFlags
pattern O_WRONLY <- ((\(FileStatusFlags n) -> n .&. _O_WRONLY > 0) -> True)
  where
    O_WRONLY = FileStatusFlags _O_WRONLY
_O_WRONLY :: CInt
_O_WRONLY = 4208223
{-# LINE 364 "src/System/Posix/FileControl.hsc" #-}
pattern O_RDWR :: FileStatusFlags
pattern O_RDWR <- ((\(FileStatusFlags n) -> n .&. _O_RDWR > 0) -> True)
  where
    O_RDWR = FileStatusFlags _O_RDWR
_O_RDWR :: CInt
_O_RDWR = 4208232
{-# LINE 365 "src/System/Posix/FileControl.hsc" #-}
pattern O_ACCMODE :: FileStatusFlags
pattern O_ACCMODE <- ((\(FileStatusFlags n) -> n .&. _O_ACCMODE > 0) -> True)
  where
    O_ACCMODE = FileStatusFlags _O_ACCMODE
_O_ACCMODE :: CInt
_O_ACCMODE = 4208239
{-# LINE 366 "src/System/Posix/FileControl.hsc" #-}

-- Open-time flags
pattern O_CREAT :: FileStatusFlags
pattern O_CREAT <- ((\(FileStatusFlags n) -> n .&. _O_CREAT > 0) -> True)
  where
    O_CREAT = FileStatusFlags _O_CREAT
_O_CREAT :: CInt
_O_CREAT = 4208270
{-# LINE 369 "src/System/Posix/FileControl.hsc" #-}
pattern O_EXCL :: FileStatusFlags
pattern O_EXCL <- ((\(FileStatusFlags n) -> n .&. _O_EXCL > 0) -> True)
  where
    O_EXCL = FileStatusFlags _O_EXCL
_O_EXCL :: CInt
_O_EXCL = 4208278
{-# LINE 370 "src/System/Posix/FileControl.hsc" #-}
pattern O_NONBLOCK :: FileStatusFlags
pattern O_NONBLOCK <- ((\(FileStatusFlags n) -> n .&. _O_NONBLOCK > 0) -> True)
  where
    O_NONBLOCK = FileStatusFlags _O_NONBLOCK
_O_NONBLOCK :: CInt
_O_NONBLOCK = 4208285
{-# LINE 371 "src/System/Posix/FileControl.hsc" #-}
pattern O_NOCTTY :: FileStatusFlags
pattern O_NOCTTY <- ((\(FileStatusFlags n) -> n .&. _O_NOCTTY > 0) -> True)
  where
    O_NOCTTY = FileStatusFlags _O_NOCTTY
_O_NOCTTY :: CInt
_O_NOCTTY = 4208296
{-# LINE 372 "src/System/Posix/FileControl.hsc" #-}
pattern O_TRUNC :: FileStatusFlags
pattern O_TRUNC <- ((\(FileStatusFlags n) -> n .&. _O_TRUNC > 0) -> True)
  where
    O_TRUNC = FileStatusFlags _O_TRUNC
_O_TRUNC :: CInt
_O_TRUNC = 4208305
{-# LINE 373 "src/System/Posix/FileControl.hsc" #-}

-- I/O operating modes
pattern O_APPEND :: FileStatusFlags
pattern O_APPEND <- ((\(FileStatusFlags n) -> n .&. _O_APPEND > 0) -> True)
  where
    O_APPEND = FileStatusFlags _O_APPEND
_O_APPEND :: CInt
_O_APPEND = 4208338
{-# LINE 376 "src/System/Posix/FileControl.hsc" #-}
pattern O_NDELAY :: FileStatusFlags
pattern O_NDELAY <- ((\(FileStatusFlags n) -> n .&. _O_NDELAY > 0) -> True)
  where
    O_NDELAY = FileStatusFlags _O_NDELAY
_O_NDELAY :: CInt
_O_NDELAY = 4208347
{-# LINE 377 "src/System/Posix/FileControl.hsc" #-}

-----------------------------------------------------------
-- Advisory and mandatory locking

newtype Flock = Flock (ForeignPtr Flock)

withFlock :: Flock -> (Ptr Flock -> IO a) -> IO a
withFlock (Flock fptr) = withForeignPtr fptr

-- | Allocate a flock structure. The allocated memory will be garbage collected
-- automatically.
newFlock :: IO Flock
newFlock = Flock <$> mallocForeignPtrBytes ((32))
{-# LINE 390 "src/System/Posix/FileControl.hsc" #-}

newtype FlockType = FlockType CInt

pattern F_RDLCK :: FlockType
pattern F_RDLCK = FlockType 4208816
{-# LINE 394 "src/System/Posix/FileControl.hsc" #-}
pattern F_WRLCK :: FlockType
pattern F_WRLCK = FlockType 4208824
{-# LINE 395 "src/System/Posix/FileControl.hsc" #-}
pattern F_UNLCK :: FlockType
pattern F_UNLCK = FlockType 4208832
{-# LINE 396 "src/System/Posix/FileControl.hsc" #-}

flockType :: Flock -> Var FlockType
flockType flock = Var get set
  where
    get = FlockType <$> withFlock flock ((\hsc_ptr -> peekByteOff hsc_ptr 0))
{-# LINE 401 "src/System/Posix/FileControl.hsc" #-}
    set (FlockType ty) = withFlock flock $ \p ->
      ((\hsc_ptr -> pokeByteOff hsc_ptr 0)) p ty
{-# LINE 403 "src/System/Posix/FileControl.hsc" #-}

newtype FlockWhence = FlockWhence CInt

pattern SEEK_SET :: FlockWhence
pattern SEEK_SET = FlockWhence 4209166
{-# LINE 407 "src/System/Posix/FileControl.hsc" #-}
pattern SEEK_CUR :: FlockWhence
pattern SEEK_CUR = FlockWhence 4209175
{-# LINE 408 "src/System/Posix/FileControl.hsc" #-}
pattern SEEK_END :: FlockWhence
pattern SEEK_END = FlockWhence 4209184
{-# LINE 409 "src/System/Posix/FileControl.hsc" #-}

flockWhence :: Flock -> Var FlockWhence
flockWhence flock = Var get set
  where
    get = FlockWhence <$> withFlock flock ((\hsc_ptr -> peekByteOff hsc_ptr 2))
{-# LINE 414 "src/System/Posix/FileControl.hsc" #-}
    set (FlockWhence whence) = withFlock flock $ \p ->
      ((\hsc_ptr -> pokeByteOff hsc_ptr 2)) p whence
{-# LINE 416 "src/System/Posix/FileControl.hsc" #-}

flockStart :: Flock -> Var FileOffset
flockStart flock = Var get set
  where
    get = withFlock flock ((\hsc_ptr -> peekByteOff hsc_ptr 8))
{-# LINE 421 "src/System/Posix/FileControl.hsc" #-}
    set offset = withFlock flock $ \p -> ((\hsc_ptr -> pokeByteOff hsc_ptr 8)) p offset
{-# LINE 422 "src/System/Posix/FileControl.hsc" #-}

flockLen :: Flock -> Var FileOffset
flockLen flock = Var get set
  where
    get = withFlock flock ((\hsc_ptr -> peekByteOff hsc_ptr 16))
{-# LINE 427 "src/System/Posix/FileControl.hsc" #-}
    set len = withFlock flock $ \p -> ((\hsc_ptr -> pokeByteOff hsc_ptr 16)) p len
{-# LINE 428 "src/System/Posix/FileControl.hsc" #-}

flockPid :: Flock -> Var ProcessID
flockPid flock = Var get set
  where
    get = withFlock flock ((\hsc_ptr -> peekByteOff hsc_ptr 24))
{-# LINE 433 "src/System/Posix/FileControl.hsc" #-}
    set pid = withFlock flock $ \p -> ((\hsc_ptr -> pokeByteOff hsc_ptr 24)) p pid
{-# LINE 434 "src/System/Posix/FileControl.hsc" #-}

-----------------------------------------------------------
-- Managing signals


{-# LINE 468 "src/System/Posix/FileControl.hsc" #-}

-----------------------------------------------------------
-- File and directory change notification (dnotify)


{-# LINE 484 "src/System/Posix/FileControl.hsc" #-}

-----------------------------------------------------------
-- File sealing


{-# LINE 498 "src/System/Posix/FileControl.hsc" #-}