1{-# LANGUAGE CPP #-}
2
3module Network.Socket.Fcntl where
4
5import qualified System.Posix.Internals
6
7#if !defined(mingw32_HOST_OS)
8import Network.Socket.Cbits
9#endif
10import Network.Socket.Imports
11
12-- | Set the nonblocking flag on Unix.
13--   On Windows, nothing is done.
14setNonBlockIfNeeded :: CInt -> IO ()
15setNonBlockIfNeeded fd =
16    System.Posix.Internals.setNonBlockingFD fd True
17
18-- | Set the close_on_exec flag on Unix.
19--   On Windows, nothing is done.
20--
21--   Since 2.7.0.0.
22setCloseOnExecIfNeeded :: CInt -> IO ()
23#if defined(mingw32_HOST_OS) || defined(ghcjs_HOST_OS)
24setCloseOnExecIfNeeded _ = return ()
25#else
26setCloseOnExecIfNeeded fd = System.Posix.Internals.setCloseOnExec fd
27#endif
28
29#if !defined(mingw32_HOST_OS)
30foreign import ccall unsafe "fcntl"
31  c_fcntl_read  :: CInt -> CInt -> CInt -> IO CInt
32#endif
33
34-- | Get the close_on_exec flag.
35--   On Windows, this function always returns 'False'.
36--
37--   Since 2.7.0.0.
38getCloseOnExec :: CInt -> IO Bool
39#if defined(mingw32_HOST_OS) || defined(ghcjs_HOST_OS)
40getCloseOnExec _ = return False
41#else
42getCloseOnExec fd = do
43    flags <- c_fcntl_read fd fGetFd 0
44    let ret = flags .&. fdCloexec
45    return (ret /= 0)
46#endif
47
48-- | Get the nonblocking flag.
49--   On Windows, this function always returns 'False'.
50--
51--   Since 2.7.0.0.
52getNonBlock :: CInt -> IO Bool
53#if defined(mingw32_HOST_OS)
54getNonBlock _ = return False
55#else
56getNonBlock fd = do
57    flags <- c_fcntl_read fd fGetFl 0
58    let ret = flags .&. oNonBlock
59    return (ret /= 0)
60#endif
61