From 12aaeecb7f1934800a880e18c9f623fbf6d378e5 Mon Sep 17 00:00:00 2001 From: Chris Martin Date: Tue, 27 Jun 2023 12:56:45 -0600 Subject: [PATCH] expose NullSockAddr, add send-with-fds functions Closes #541 --- CHANGELOG.md | 7 +++++++ Network/Socket/ByteString.hs | 1 + Network/Socket/ByteString/IO.hsc | 17 +++++++++++++++++ Network/Socket/ByteString/Lazy.hs | 11 +++++++++++ Network/Socket/Internal.hs | 3 +++ Network/Socket/Types.hsc | 14 ++++++++++++++ Network/Socket/Unix.hsc | 7 ------- network.cabal | 2 +- 8 files changed, 54 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index efebc24d..34fddc98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## Version 3.1.5.0 + +* [#541](https://github.com/haskell/network/issues/541) + * Export `Network.Socket.Internal.NullSockAddr` + * Add `Network.Socket.ByteString.sendManyWithFds` + * Add `Network.Socket.ByteString.Lazy.sendWithFds` + ## Version 3.1.4.0 * Install and use afunix_compat.h header. diff --git a/Network/Socket/ByteString.hs b/Network/Socket/ByteString.hs index f5810212..ec47edcf 100644 --- a/Network/Socket/ByteString.hs +++ b/Network/Socket/ByteString.hs @@ -29,6 +29,7 @@ module Network.Socket.ByteString -- $vectored , sendMany , sendManyTo + , sendManyWithFds -- * Receive data from a socket , recv diff --git a/Network/Socket/ByteString/IO.hsc b/Network/Socket/ByteString/IO.hsc index 8c89198e..30cd0c98 100644 --- a/Network/Socket/ByteString/IO.hsc +++ b/Network/Socket/ByteString/IO.hsc @@ -24,6 +24,7 @@ module Network.Socket.ByteString.IO -- $vectored , sendMany , sendManyTo + , sendManyWithFds -- * Receive data from a socket , recv @@ -53,6 +54,7 @@ import Data.ByteString.Internal (create, ByteString(..)) import Foreign.ForeignPtr (withForeignPtr) import Foreign.Marshal.Utils (with) import Network.Socket.Internal +import System.Posix.Types (Fd(..)) import Network.Socket.Flag @@ -217,6 +219,21 @@ sendManyTo s cs addr = do peek send_ptr #endif +-- | Send data and file descriptors over a UNIX-domain socket in +-- a single system call. This function does not work on Windows. +sendManyWithFds :: Socket -- ^ Socket + -> [ByteString] -- ^ Data to send + -> [Fd] -- ^ File descriptors + -> IO () +sendManyWithFds s bss fds = + void $ + withBufSizs bss $ \bufsizs -> + sendBufMsg s addr bufsizs cmsgs flags + where + addr = NullSockAddr + cmsgs = encodeCmsg <$> fds + flags = mempty + -- ---------------------------------------------------------------------------- -- Receiving diff --git a/Network/Socket/ByteString/Lazy.hs b/Network/Socket/ByteString/Lazy.hs index 7a7d910c..b3df870c 100644 --- a/Network/Socket/ByteString/Lazy.hs +++ b/Network/Socket/ByteString/Lazy.hs @@ -23,6 +23,7 @@ module Network.Socket.ByteString.Lazy ( -- * Send data to a socket send , sendAll + , sendWithFds -- * Receive data from a socket , getContents , recv @@ -33,6 +34,7 @@ import Network.Socket (ShutdownCmd (..), shutdown) import Prelude hiding (getContents) import System.IO.Unsafe (unsafeInterleaveIO) import System.IO.Error (catchIOError) +import System.Posix.Types (Fd(..)) #if defined(mingw32_HOST_OS) import Network.Socket.ByteString.Lazy.Windows (send, sendAll) @@ -41,10 +43,19 @@ import Network.Socket.ByteString.Lazy.Posix (send, sendAll) #endif import qualified Data.ByteString as S +import qualified Data.ByteString.Lazy as L import qualified Network.Socket.ByteString as N import Network.Socket.Imports import Network.Socket.Types +-- | Send data and file descriptors over a UNIX-domain socket in +-- a single system call. This function does not work on Windows. +sendWithFds :: Socket -- ^ Socket + -> ByteString -- ^ Data to send + -> [Fd] -- ^ File descriptors + -> IO () +sendWithFds s lbs fds = N.sendManyWithFds s (L.toChunks lbs) fds + -- ----------------------------------------------------------------------------- -- Receiving -- | Receive data from the socket. The socket must be in a connected diff --git a/Network/Socket/Internal.hs b/Network/Socket/Internal.hs index 57690647..94769e85 100644 --- a/Network/Socket/Internal.hs +++ b/Network/Socket/Internal.hs @@ -48,6 +48,9 @@ module Network.Socket.Internal -- * Initialization , withSocketsDo + -- * Null socket address type + , NullSockAddr (..) + -- * Low-level helpers , zeroMemory ) where diff --git a/Network/Socket/Types.hsc b/Network/Socket/Types.hsc index 3f57dc41..13fe3a8d 100644 --- a/Network/Socket/Types.hsc +++ b/Network/Socket/Types.hsc @@ -67,6 +67,9 @@ module Network.Socket.Types ( , pokeSockAddr , withSockAddr + -- * Null socket address type + , NullSockAddr(..) + -- * Unsorted , ProtocolNumber , defaultProtocol @@ -1021,6 +1024,17 @@ withNewSocketAddress f = allocaBytes sockaddrStorageLen $ \ptr -> do zeroMemory ptr $ fromIntegral sockaddrStorageLen f ptr sockaddrStorageLen +------------------------------------------------------------------------ + +-- | A null 'SocketAddress' for situations where a socket address +-- parameter is optional. +data NullSockAddr = NullSockAddr + +instance SocketAddress NullSockAddr where + sizeOfSocketAddress _ = 0 + peekSocketAddress _ = return NullSockAddr + pokeSocketAddress _ _ = return () + ------------------------------------------------------------------------ -- Socket addresses diff --git a/Network/Socket/Unix.hsc b/Network/Socket/Unix.hsc index 1325ba21..709fb1c8 100644 --- a/Network/Socket/Unix.hsc +++ b/Network/Socket/Unix.hsc @@ -133,13 +133,6 @@ getPeerEid _ = return (0, 0) isUnixDomainSocketAvailable :: Bool isUnixDomainSocketAvailable = True -data NullSockAddr = NullSockAddr - -instance SocketAddress NullSockAddr where - sizeOfSocketAddress _ = 0 - peekSocketAddress _ = return NullSockAddr - pokeSocketAddress _ _ = return () - -- | Send a file descriptor over a UNIX-domain socket. -- This function does not work on Windows. sendFd :: Socket -> CInt -> IO () diff --git a/network.cabal b/network.cabal index e9bd5403..6d33af60 100644 --- a/network.cabal +++ b/network.cabal @@ -1,6 +1,6 @@ cabal-version: 1.18 name: network -version: 3.1.4.0 +version: 3.1.5.0 license: BSD3 license-file: LICENSE maintainer: Kazu Yamamoto, Evan Borden