{-# LANGUAGE CPP #-} {-# LANGUAGE OverloadedStrings #-} module Network.Run.Core ( resolve , openSocket , openServerSocket ) where import qualified Control.Exception as E import Network.Socket resolve :: SocketType -> Maybe HostName -> ServiceName -> Bool -> IO AddrInfo resolve :: SocketType -> Maybe HostName -> HostName -> Bool -> IO AddrInfo resolve SocketType socketType Maybe HostName mhost HostName port Bool passive = forall a. [a] -> a head forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> Maybe AddrInfo -> Maybe HostName -> Maybe HostName -> IO [AddrInfo] getAddrInfo (forall a. a -> Maybe a Just AddrInfo hints) Maybe HostName mhost (forall a. a -> Maybe a Just HostName port) where hints :: AddrInfo hints = AddrInfo defaultHints { addrSocketType :: SocketType addrSocketType = SocketType socketType , addrFlags :: [AddrInfoFlag] addrFlags = if Bool passive then [AddrInfoFlag AI_PASSIVE] else [] } #if !MIN_VERSION_network(3,1,2) openSocket :: AddrInfo -> IO Socket openSocket addr = socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr) #endif openServerSocket :: AddrInfo -> IO Socket openServerSocket :: AddrInfo -> IO Socket openServerSocket AddrInfo addr = forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c E.bracketOnError (AddrInfo -> IO Socket openSocket AddrInfo addr) Socket -> IO () close forall a b. (a -> b) -> a -> b $ \Socket sock -> do Socket -> SocketOption -> Int -> IO () setSocketOption Socket sock SocketOption ReuseAddr Int 1 forall r. Socket -> (CInt -> IO r) -> IO r withFdSocket Socket sock forall a b. (a -> b) -> a -> b $ CInt -> IO () setCloseOnExecIfNeeded Socket -> SockAddr -> IO () bind Socket sock forall a b. (a -> b) -> a -> b $ AddrInfo -> SockAddr addrAddress AddrInfo addr forall (m :: * -> *) a. Monad m => a -> m a return Socket sock