11{-# LANGUAGE CPP #-}
2+ {-# LANGUAGE ScopedTypeVariables #-}
23
34#include "HsNet.h"
45##include "HsNetDef.h"
@@ -13,30 +14,32 @@ module Network.Socket.Unix (
1314 , getPeerEid
1415 ) where
1516
16- import System.Posix.Types (Fd (.. ))
17-
17+ import Foreign.Marshal.Alloc (allocaBytes )
1818import Network.Socket.Buffer
19+ import Network.Socket.Fcntl
1920import Network.Socket.Imports
21+ import Network.Socket.Types
22+ import System.Posix.Types (Fd (.. ))
23+
2024#if defined(mingw32_HOST_OS)
25+ import Network.Socket.Syscall
2126import Network.Socket.Win32.Cmsg
27+ import System.Directory
28+ import System.IO
29+ import System.IO.Temp
2230#else
31+ import Foreign.Marshal.Array (peekArray )
32+ import Network.Socket.Internal
2333import Network.Socket.Posix.Cmsg
2434#endif
25- import Network.Socket.Types
2635
2736#if defined(HAVE_GETPEEREID)
2837import System.IO.Error (catchIOError )
2938#endif
3039#ifdef HAVE_GETPEEREID
3140import Foreign.Marshal.Alloc (alloca )
3241#endif
33- #ifdef DOMAIN_SOCKET_SUPPORT
34- import Foreign.Marshal.Alloc (allocaBytes )
35- import Foreign.Marshal.Array (peekArray )
3642
37- import Network.Socket.Fcntl
38- import Network.Socket.Internal
39- #endif
4043#ifdef HAVE_STRUCT_UCRED_SO_PEERCRED
4144import Network.Socket.Options
4245#endif
@@ -126,11 +129,7 @@ getPeerEid _ = return (0, 0)
126129--
127130-- Since 2.7.0.0.
128131isUnixDomainSocketAvailable :: Bool
129- #if defined(DOMAIN_SOCKET_SUPPORT)
130132isUnixDomainSocketAvailable = True
131- #else
132- isUnixDomainSocketAvailable = False
133- #endif
134133
135134data NullSockAddr = NullSockAddr
136135
@@ -143,33 +142,25 @@ instance SocketAddress NullSockAddr where
143142-- Use this function in the case where 'isUnixDomainSocketAvailable' is
144143-- 'True'.
145144sendFd :: Socket -> CInt -> IO ()
146- #if defined(DOMAIN_SOCKET_SUPPORT)
147145sendFd s outfd = void $ allocaBytes dummyBufSize $ \ buf -> do
148146 let cmsg = encodeCmsg $ Fd outfd
149147 sendBufMsg s NullSockAddr [(buf,dummyBufSize)] [cmsg] mempty
150148 where
151149 dummyBufSize = 1
152- #else
153- sendFd _ _ = error " Network.Socket.sendFd"
154- #endif
155150
156151-- | Receive a file descriptor over a UNIX-domain socket. Note that the resulting
157152-- file descriptor may have to be put into non-blocking mode in order to be
158153-- used safely. See 'setNonBlockIfNeeded'.
159154-- Use this function in the case where 'isUnixDomainSocketAvailable' is
160155-- 'True'.
161156recvFd :: Socket -> IO CInt
162- #if defined(DOMAIN_SOCKET_SUPPORT)
163157recvFd s = allocaBytes dummyBufSize $ \ buf -> do
164158 (NullSockAddr , _, cmsgs, _) <- recvBufMsg s [(buf,dummyBufSize)] 32 mempty
165159 case (lookupCmsg CmsgIdFd cmsgs >>= decodeCmsg) :: Maybe Fd of
166160 Nothing -> return (- 1 )
167161 Just (Fd fd) -> return fd
168162 where
169163 dummyBufSize = 16
170- #else
171- recvFd _ = error " Network.Socket.recvFd"
172- #endif
173164
174165-- | Build a pair of connected socket objects.
175166-- For portability, use this function in the case
@@ -179,7 +170,21 @@ socketPair :: Family -- Family Name (usually AF_UNIX)
179170 -> SocketType -- Socket Type (usually Stream)
180171 -> ProtocolNumber -- Protocol Number
181172 -> IO (Socket , Socket ) -- unnamed and connected.
182- #if defined(DOMAIN_SOCKET_SUPPORT)
173+ #if defined(mingw32_HOST_OS)
174+ socketPair _ _ _ = withSystemTempFile " temp-for-pair" $ \ file hdl -> do
175+ hClose hdl
176+ removeFile file
177+ listenSock <- socket AF_UNIX Stream defaultProtocol
178+ bind listenSock $ SockAddrUnix file
179+ listen listenSock 10
180+ clientSock <- socket AF_UNIX Stream defaultProtocol
181+ connect clientSock $ SockAddrUnix file
182+ (serverSock, _ :: SockAddr ) <- accept listenSock
183+ close listenSock
184+ withFdSocket clientSock setNonBlockIfNeeded
185+ withFdSocket serverSock setNonBlockIfNeeded
186+ return (clientSock, serverSock)
187+ #else
183188socketPair family stype protocol =
184189 allocaBytes (2 * sizeOf (1 :: CInt )) $ \ fdArr -> do
185190 let c_stype = packSocketType stype
@@ -194,6 +199,4 @@ socketPair family stype protocol =
194199
195200foreign import ccall unsafe " socketpair"
196201 c_socketpair :: CInt -> CInt -> CInt -> Ptr CInt -> IO CInt
197- #else
198- socketPair _ _ _ = error " Network.Socket.socketPair"
199202#endif
0 commit comments