    {-# LANGUAGE CPP #-}

    module Network.Socket.Fcntl where

    import qualified System.Posix.Internals

    #if !defined(mingw32_HOST_OS)
    import Network.Socket.Cbits
    #endif
    import Network.Socket.Imports

    -- | Set the nonblocking flag on Unix.
    --   On Windows, nothing is done.
    setNonBlockIfNeeded :: CInt -> IO ()
    setNonBlockIfNeeded :: CInt -> IO ()
    setNonBlockIfNeeded CInt
    fd =
        CInt -> Bool -> IO ()
    System.Posix.Internals.setNonBlockingFD CInt
    fd Bool
    True

    -- | Set the close_on_exec flag on Unix.
    --   On Windows, nothing is done.
    --
    --   Since 2.7.0.0.
    setCloseOnExecIfNeeded :: CInt -> IO ()
    #if defined(mingw32_HOST_OS) || defined(ghcjs_HOST_OS)
    setCloseOnExecIfNeeded _ = return ()
    #else
    setCloseOnExecIfNeeded :: CInt -> IO ()
    setCloseOnExecIfNeeded CInt
    fd = CInt -> IO ()
    System.Posix.Internals.setCloseOnExec CInt
    fd
    #endif

    #if !defined(mingw32_HOST_OS)
    foreign import ccall unsafe "fcntl"
      c_fcntl_read  :: CInt -> CInt -> CInt -> IO CInt
    #endif

    -- | Get the close_on_exec flag.
    --   On Windows, this function always returns 'False'.
    --
    --   Since 2.7.0.0.
    getCloseOnExec :: CInt -> IO Bool
    #if defined(mingw32_HOST_OS) || defined(ghcjs_HOST_OS)
    getCloseOnExec _ = return False
    #else
    getCloseOnExec :: CInt -> IO Bool
    getCloseOnExec CInt
    fd = do
        flags <- CInt -> CInt -> CInt -> IO CInt
    c_fcntl_read CInt
    fd CInt
    fGetFd CInt
    0
        let ret = CInt
    flags CInt -> CInt -> CInt
    forall a. Bits a => a -> a -> a
    .&. CInt
    fdCloexec
        return (ret /= 0)
    #endif

    -- | Get the nonblocking flag.
    --   On Windows, this function always returns 'False'.
    --
    --   Since 2.7.0.0.
    getNonBlock :: CInt -> IO Bool
    #if defined(mingw32_HOST_OS)
    getNonBlock _ = return False
    #else
    getNonBlock :: CInt -> IO Bool
    getNonBlock CInt
    fd = do
        flags <- CInt -> CInt -> CInt -> IO CInt
    c_fcntl_read CInt
    fd CInt
    fGetFl CInt
    0
        let ret = CInt
    flags CInt -> CInt -> CInt
    forall a. Bits a => a -> a -> a
    .&. CInt
    oNonBlock
        return (ret /= 0)
    #endif