posix-socket 0.2 → 0.3
raw patch · 5 files changed
+96/−37 lines, 5 files
Files
- README.md +13/−0
- posix-socket.cabal +3/−2
- src/System/Posix/Socket.hsc +57/−29
- src/System/Posix/Socket/Inet.hsc +15/−4
- src/System/Posix/Socket/Local.hsc +8/−2
+ README.md view
@@ -0,0 +1,13 @@+POSIX-Socket+===========++[](https://travis-ci.org/mvv/posix-socket) [](http://hackage.haskell.org/package/posix-socket)++This package provides bindings to the POSIX socket API.++Installation+------------+The usual:++ $ cabal install+
posix-socket.cabal view
@@ -1,5 +1,5 @@ Name: posix-socket-Version: 0.2+Version: 0.3 Category: System Stability: experimental Synopsis: Bindings to the POSIX socket API@@ -17,8 +17,9 @@ Extra-Source-Files: include/posix-socket.macros.h+ README.md -Tested-With: GHC==7.10.3, GHC==8.0.2, GHC==8.2.2+Tested-With: GHC==7.10.3, GHC==8.0.2, GHC==8.2.2, GHC==8.4.1 Cabal-Version: >= 1.6.0 Build-Type: Simple
src/System/Posix/Socket.hsc view
@@ -4,6 +4,7 @@ {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE EmptyDataDecls #-} {-# LANGUAGE DoAndIfThenElse #-} {-# LANGUAGE TupleSections #-} {-# LANGUAGE TypeFamilies #-}@@ -31,9 +32,12 @@ , SockProto(..) , defaultSockProto , SockOpt(..)- , SO_ERROR(..)- , SO_KEEPALIVE(..)- , SO_REUSEADDR(..)+ , SO_ERROR+ , pattern SO_ERROR+ , SO_KEEPALIVE+ , pattern SO_KEEPALIVE+ , SO_REUSEADDR+ , pattern SO_REUSEADDR , SockOps(..) , MsgFlags(..) , pattern MSG_PEEK@@ -77,6 +81,9 @@ , sendTo' , sendTo -- ** Closing+ , pattern SHUT_RD+ , pattern SHUT_WR+ , pattern SHUT_RDWR , shutdown , close ) where@@ -173,7 +180,7 @@ class SockAddr (SockFamilyAddr f) ⇒ SockFamily f where type SockFamilyAddr f -- | Socket family code.- sockFamilyCode ∷ f → CInt+ sockFamilyCode ∷ Proxy f → CInt -- | Socket type. newtype SockType = SockType CInt deriving (Typeable, Eq, Ord, Show, Storable)@@ -219,16 +226,19 @@ -- | Whether option is writable type SockOptWritable o ∷ Bool -- | Convert to FFI-level value- sockOptRaw ∷ o → SockOptValue o → SockOptRaw o+ sockOptRaw ∷ Proxy o → SockOptValue o → SockOptRaw o -- | Convert from FFI-level value- sockOptValue ∷ o → SockOptRaw o → SockOptValue o+ sockOptValue ∷ Proxy o → SockOptRaw o → SockOptValue o -- | Option protocol level- sockOptLevel ∷ o → CInt+ sockOptLevel ∷ Proxy o → CInt -- | Option code- sockOptCode ∷ o → CInt+ sockOptCode ∷ Proxy o → CInt -data SO_ERROR = SO_ERROR deriving (Typeable, Eq, Show)+data SO_ERROR deriving Typeable +pattern SO_ERROR ∷ Proxy SO_ERROR+pattern SO_ERROR = Proxy+ instance SockOpt SO_ERROR where type SockOptValue SO_ERROR = Errno type SockOptRaw SO_ERROR = CInt@@ -239,8 +249,11 @@ sockOptLevel _ = #const SOL_SOCKET sockOptCode _ = #const SO_ERROR -data SO_KEEPALIVE = SO_KEEPALIVE deriving (Typeable, Eq, Show)+data SO_KEEPALIVE deriving Typeable +pattern SO_KEEPALIVE ∷ Proxy SO_KEEPALIVE+pattern SO_KEEPALIVE = Proxy+ instance SockOpt SO_KEEPALIVE where type SockOptValue SO_KEEPALIVE = Bool type SockOptRaw SO_KEEPALIVE = CInt@@ -252,8 +265,11 @@ sockOptLevel _ = #const SOL_SOCKET sockOptCode _ = #const SO_KEEPALIVE -data SO_REUSEADDR = SO_REUSEADDR deriving (Typeable, Eq, Show)+data SO_REUSEADDR deriving Typeable +pattern SO_REUSEADDR ∷ Proxy SO_REUSEADDR+pattern SO_REUSEADDR = Proxy+ instance SockOpt SO_REUSEADDR where type SockOptValue SO_REUSEADDR = Bool type SockOptRaw SO_REUSEADDR = CInt@@ -322,7 +338,7 @@ where size = sockAddrSize addr peekAddrOfSize ∷ SockFamily f- ⇒ f → Ptr (SockFamilyAddr f) → Ptr #{itype socklen_t}+ ⇒ Proxy f → Ptr (SockFamilyAddr f) → Ptr #{itype socklen_t} → IO (SockFamilyAddr f) peekAddrOfSize fam p pSize = do outSize ← fromIntegral <$> peek pSize@@ -332,7 +348,7 @@ peekSockAddr p outSize withAddr ∷ SockFamily f- ⇒ f+ ⇒ Proxy f → SockFamilyAddr f → (Ptr (SockFamilyAddr f) → #{itype socklen_t} → IO α) → IO α@@ -347,7 +363,7 @@ -- | Create a socket. The underlying file descriptor is non-blocking. All -- blocking operations are done via the GHC event manager. See /socket(2)/. socket ∷ (SockFamily f, MonadBase IO μ)- ⇒ f → SockType → SockProto → μ (Socket f)+ ⇒ Proxy f → SockType → SockProto → μ (Socket f) socket f (SockType t) p = liftBase $ do fd ← throwErrnoIfMinus1 "socket" $ c_socket (sockFamilyCode f)@@ -360,7 +376,7 @@ fmap Socket $ newMVar $ Fd fd getFdOpt ∷ ∀ o . (SockOpt o, SockOptReadable o ~ 'True)- ⇒ Fd → o → IO (SockOptValue o)+ ⇒ Fd → Proxy o → IO (SockOptValue o) getFdOpt fd o = alloca $ \p → with (fromIntegral $ sizeOf (undefined ∷ SockOptRaw o)) $ \pSize → do@@ -370,12 +386,12 @@ -- | Get socket option value. See /getsockopt(2)/. getSockOpt ∷ (SockOpt o, SockOptReadable o ~ 'True, MonadBase IO μ)- ⇒ Socket f → o → μ (SockOptValue o)+ ⇒ Socket f → Proxy o → μ (SockOptValue o) getSockOpt s o = withSocketFd s $ \fd → getFdOpt fd o -- | Set socket option value. See /setsockopt(2)/. setSockOpt ∷ (SockOpt o, SockOptWritable o ~ 'True, MonadBase IO μ)- ⇒ Socket f → o → SockOptValue o → μ ()+ ⇒ Socket f → Proxy o → SockOptValue o → μ () setSockOpt s o v = withSocketFd s $ \fd → with raw $ \p → throwErrnoIfMinus1_ "setSockOpt" $@@ -387,7 +403,7 @@ bind ∷ ∀ f μ . (SockFamily f, MonadBase IO μ) ⇒ Socket f → SockFamilyAddr f → μ () bind s addr = withSocketFd s $ \fd →- withAddr (undefined ∷ f) addr $ \p size →+ withAddr (Proxy ∷ Proxy f) addr $ \p size → throwErrnoIfMinus1_ "bind" $ c_bind fd p $ fromIntegral size -- | Connect socket to the specified address. This operation blocks.@@ -395,7 +411,7 @@ connect ∷ ∀ f μ . (SockFamily f, MonadBase IO μ) ⇒ Socket f → SockFamilyAddr f → μ () connect s addr = withSocketFd s $ \fd →- withAddr (undefined ∷ f) addr $ \p size →+ withAddr (Proxy ∷ Proxy f) addr $ \p size → doConnect fd p $ fromIntegral size where doConnect fd p size = do r ← c_connect fd p size@@ -417,7 +433,7 @@ tryConnect ∷ ∀ f μ . (SockFamily f, MonadBase IO μ) ⇒ Socket f → SockFamilyAddr f → μ Bool tryConnect s addr = withSocketFd s $ \fd →- withAddr (undefined ∷ f) addr $ \p size → do+ withAddr (Proxy ∷ Proxy f) addr $ \p size → do r ← c_connect fd p $ fromIntegral size if r == -1 then do@@ -453,7 +469,7 @@ doAccept fd p pSize _ → throwErrno "accept" else do- addr ← peekAddrOfSize (undefined ∷ f) p pSize+ addr ← peekAddrOfSize (Proxy ∷ Proxy f) p pSize let accFd = Fd cfd #ifndef HAVE_ACCEPT_WITH_FLAGS onException (setNonBlockingFD accFd True) (closeFd accFd)@@ -478,7 +494,7 @@ e | e == eAGAIN || e == eWOULDBLOCK → return Nothing _ → throwErrno "accept" else do- addr ← peekAddrOfSize (undefined ∷ f) p pSize+ addr ← peekAddrOfSize (Proxy ∷ Proxy f) p pSize let accFd = Fd cfd #ifndef HAVE_ACCEPT_WITH_FLAGS onException (setNonBlockingFD accFd True) (closeFd accFd)@@ -492,7 +508,7 @@ allocaMaxAddr (Proxy ∷ Proxy (SockFamilyAddr f)) $ \p size → with size $ \pSize → do throwErrnoIfMinus1_ "getLocalAddr" $ c_getsockname fd p pSize- peekAddrOfSize (undefined ∷ f) p pSize+ peekAddrOfSize (Proxy ∷ Proxy f) p pSize -- | Get the remote address. See /getpeername(2)/. getRemoteAddr ∷ ∀ f μ . (SockFamily f, MonadBase IO μ)@@ -501,7 +517,7 @@ allocaMaxAddr (Proxy ∷ Proxy (SockFamilyAddr f)) $ \p size → with size $ \pSize → do throwErrnoIfMinus1_ "getRemoteAddr" $ c_getpeername fd p pSize- peekAddrOfSize (undefined ∷ f) p pSize+ peekAddrOfSize (Proxy ∷ Proxy f) p pSize -- | Check if socket has out-of-band data. See /sockatmark(3)/. hasOobData ∷ MonadBase IO μ ⇒ Socket f → μ Bool@@ -516,7 +532,7 @@ throwInval loc = throwCustomErrno loc eINVAL recvBufsFromFd ∷ ∀ f . SockFamily f- ⇒ f → Fd → [(Ptr Word8, Int)] → MsgFlags+ ⇒ Proxy f → Fd → [(Ptr Word8, Int)] → MsgFlags → IO (Maybe (SockFamilyAddr f), Int, MsgFlags) recvBufsFromFd _ fd bufs' flags = do let (bufs, bufs'') = partition ((> 0) . snd) bufs'@@ -565,7 +581,7 @@ ⇒ Socket f → [(Ptr Word8, Int)] → MsgFlags → μ (Maybe (SockFamilyAddr f), Int, MsgFlags) recvBufsFrom' s bufs flags = withSocketFd s $ \fd →- recvBufsFromFd (undefined ∷ f) fd bufs flags+ recvBufsFromFd (Proxy ∷ Proxy f) fd bufs flags -- | Receive a message from a connected socket, possibly utilizing multiple -- memory buffers. See /recvmsg(2)/.@@ -617,12 +633,12 @@ → μ (SockFamilyAddr f, Int, MsgFlags) -- ^ Received message source address, length, and flags recvBufsFrom s bufs flags = withSocketFd s $ \fd → do- (mAddr, n, flags') ← recvBufsFromFd (undefined ∷ f) fd bufs flags+ (mAddr, n, flags') ← recvBufsFromFd (Proxy ∷ Proxy f) fd bufs flags let getpeername = allocaMaxAddr (Proxy ∷ Proxy (SockFamilyAddr f)) $ \p size → with size $ \pSize → do throwErrnoIfMinus1_ "recv" $ c_getpeername fd p pSize- peekAddrOfSize (undefined ∷ f) p pSize+ peekAddrOfSize (Proxy ∷ Proxy f) p pSize (, n, flags') <$> maybe getpeername return mAddr -- | Receive a message from an unconnected socket. This operation blocks.@@ -697,7 +713,7 @@ doSend case mAddr of Just addr →- withAddr (undefined ∷ f) addr $ \pAddr addrLen → do+ withAddr (Proxy ∷ Proxy f) addr $ \pAddr addrLen → do #{poke struct msghdr, msg_name} pHdr pAddr #{poke struct msghdr, msg_namelen} pHdr addrLen cont@@ -828,6 +844,18 @@ → SockFamilyAddr f -- ^ Message destination address → μ Int -- ^ The number of bytes sent sendTo s bs addr = sendTo' s bs noFlags addr++-- | An alias for 'RecvSockOps'.+pattern SHUT_RD ∷ SockOps+pattern SHUT_RD = RecvSockOps++-- | An alias for 'SendSockOps'.+pattern SHUT_WR ∷ SockOps+pattern SHUT_WR = SendSockOps++-- | An alias for 'AllSockOps'.+pattern SHUT_RDWR ∷ SockOps+pattern SHUT_RDWR = AllSockOps -- | Shut down a part of a full-duplex connection. See /shutdown(2)/. shutdown ∷ MonadBase IO μ ⇒ Socket f → SockOps → μ ()
src/System/Posix/Socket/Inet.hsc view
@@ -2,6 +2,8 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE EmptyDataDecls #-}+{-# LANGUAGE PatternSynonyms #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE TypeSynonymInstances #-}@@ -9,11 +11,14 @@ -- | Internet address families. module System.Posix.Socket.Inet- ( AF_INET(..)- , AF_INET6(..)+ ( AF_INET+ , pattern AF_INET+ , AF_INET6+ , pattern AF_INET6 ) where import Data.Typeable (Typeable)+import Data.Proxy (Proxy(..)) import Network.IP.Addr import Control.Applicative ((<$>), (<*>)) import Foreign.C.Types (CSize)@@ -25,8 +30,11 @@ #include <netinet/ip6.h> -- | IPv4 socket family.-data AF_INET = AF_INET deriving (Typeable, Eq, Show)+data AF_INET deriving Typeable +pattern AF_INET ∷ Proxy AF_INET+pattern AF_INET = Proxy+ instance SockAddr Inet4Addr where sockAddrMaxSize _ = #{size struct sockaddr_in} sockAddrSize _ = #{size struct sockaddr_in}@@ -46,7 +54,10 @@ sockFamilyCode _ = #const AF_INET -- | IPv6 socket family.-data AF_INET6 = AF_INET6 deriving (Typeable, Eq, Show)+data AF_INET6 deriving Typeable++pattern AF_INET6 ∷ Proxy AF_INET6+pattern AF_INET6 = Proxy instance SockAddr Inet6Addr where sockAddrMaxSize _ = #{size struct sockaddr_in6}
src/System/Posix/Socket/Local.hsc view
@@ -2,13 +2,16 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE EmptyDataDecls #-}+{-# LANGUAGE PatternSynonyms #-} {-# LANGUAGE TypeFamilies #-} -- | Local address family. module System.Posix.Socket.Local ( LocalAddr(..) , aLocalAddr- , AF_LOCAL(..)+ , AF_LOCAL+ , pattern AF_LOCAL ) where import Data.Typeable (Typeable)@@ -27,7 +30,10 @@ #include <sys/un.h> -- | Local socket family.-data AF_LOCAL = AF_LOCAL deriving (Typeable, Eq, Show)+data AF_LOCAL deriving Typeable++pattern AF_LOCAL ∷ Proxy AF_LOCAL+pattern AF_LOCAL = Proxy -- | Local socket address. data LocalAddr = LocalAddr ByteString