1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
|
{-# LANGUAGE CPP #-}
{-# LANGUAGE OverloadedStrings #-}
module Network.Run.Core (
resolve,
openSocket,
openClientSocket,
openServerSocket,
gclose,
) where
import qualified Control.Exception as E
import Network.Socket
resolve
:: SocketType
-> Maybe HostName
-> ServiceName
-> [AddrInfoFlag]
-> IO AddrInfo
resolve socketType mhost port flags =
head <$> getAddrInfo (Just hints) mhost (Just port)
where
hints =
defaultHints
{ addrSocketType = socketType
, addrFlags = flags
}
#if !MIN_VERSION_network(3,1,2)
openSocket :: AddrInfo -> IO Socket
openSocket addr = socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr)
#endif
openClientSocket :: AddrInfo -> IO Socket
openClientSocket ai = do
sock <- openSocket ai
connect sock $ addrAddress ai
return sock
-- | Open socket for server use
--
-- The socket is configured to
--
-- * allow reuse of local addresses (SO_REUSEADDR)
-- * automatically be closed during a successful @execve@ (FD_CLOEXEC)
-- * bind to the address specified
openServerSocket :: AddrInfo -> IO Socket
openServerSocket addr = E.bracketOnError (openSocket addr) close $ \sock -> do
setSocketOption sock ReuseAddr 1
withFdSocket sock $ setCloseOnExecIfNeeded
bind sock $ addrAddress addr
return sock
gclose :: Socket -> IO ()
#if MIN_VERSION_network(3,1,1)
gclose sock = gracefulClose sock 5000
#else
gclose = close
#endif
|