Skip to content

Commit e7165d0

Browse files
Merge pull request #554 from kazu-yamamoto/sockpair
Sockpair
2 parents 34f74b4 + 0c2df5c commit e7165d0

File tree

5 files changed

+30
-48
lines changed

5 files changed

+30
-48
lines changed

Network/Socket/Info.hsc

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -413,11 +413,7 @@ unpackBits ((k,v):xs) r
413413
-- SockAddr
414414

415415
instance Show SockAddr where
416-
#if defined(DOMAIN_SOCKET_SUPPORT)
417416
showsPrec _ (SockAddrUnix str) = showString str
418-
#else
419-
showsPrec _ SockAddrUnix{} = error "showsPrec: not supported"
420-
#endif
421417
showsPrec _ (SockAddrInet port ha)
422418
= showHostAddress ha
423419
. showString ":"

Network/Socket/Types.hsc

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,7 @@ import GHC.IO (IO (..))
9393

9494
import qualified Text.Read as P
9595

96-
#if defined(DOMAIN_SOCKET_SUPPORT)
9796
import Foreign.Marshal.Array
98-
#endif
9997

10098
import Network.Socket.Imports
10199

@@ -1075,11 +1073,7 @@ isSupportedSockAddr :: SockAddr -> Bool
10751073
isSupportedSockAddr addr = case addr of
10761074
SockAddrInet{} -> True
10771075
SockAddrInet6{} -> True
1078-
#if defined(DOMAIN_SOCKET_SUPPORT)
10791076
SockAddrUnix{} -> True
1080-
#else
1081-
SockAddrUnix{} -> False
1082-
#endif
10831077

10841078
instance SocketAddress SockAddr where
10851079
sizeOfSocketAddress = sizeOfSockAddr
@@ -1098,7 +1092,6 @@ type CSaFamily = (#type sa_family_t)
10981092
-- 'SockAddr'. This function differs from 'Foreign.Storable.sizeOf'
10991093
-- in that the value of the argument /is/ used.
11001094
sizeOfSockAddr :: SockAddr -> Int
1101-
#if defined(DOMAIN_SOCKET_SUPPORT)
11021095
# ifdef linux_HOST_OS
11031096
-- http://man7.org/linux/man-pages/man7/unix.7.html says:
11041097
-- "an abstract socket address is distinguished (from a
@@ -1118,9 +1111,6 @@ sizeOfSockAddr (SockAddrUnix path) =
11181111
# else
11191112
sizeOfSockAddr SockAddrUnix{} = #const sizeof(struct sockaddr_un)
11201113
# endif
1121-
#else
1122-
sizeOfSockAddr SockAddrUnix{} = error "sizeOfSockAddr: not supported"
1123-
#endif
11241114
sizeOfSockAddr SockAddrInet{} = #const sizeof(struct sockaddr_in)
11251115
sizeOfSockAddr SockAddrInet6{} = #const sizeof(struct sockaddr_in6)
11261116

@@ -1135,10 +1125,8 @@ withSockAddr addr f = do
11351125
-- structure, and attempting to do so could overflow the allocated storage
11361126
-- space. This constant holds the maximum allowable path length.
11371127
--
1138-
#if defined(DOMAIN_SOCKET_SUPPORT)
11391128
unixPathMax :: Int
11401129
unixPathMax = #const sizeof(((struct sockaddr_un *)NULL)->sun_path)
1141-
#endif
11421130

11431131
-- We can't write an instance of 'Storable' for 'SockAddr' because
11441132
-- @sockaddr@ is a sum type of variable size but
@@ -1149,7 +1137,6 @@ unixPathMax = #const sizeof(((struct sockaddr_un *)NULL)->sun_path)
11491137

11501138
-- | Write the given 'SockAddr' to the given memory location.
11511139
pokeSockAddr :: Ptr a -> SockAddr -> IO ()
1152-
#if defined(DOMAIN_SOCKET_SUPPORT)
11531140
pokeSockAddr p sa@(SockAddrUnix path) = do
11541141
when (length path > unixPathMax) $ error
11551142
$ "pokeSockAddr: path is too long in SockAddrUnix " <> show path
@@ -1162,9 +1149,6 @@ pokeSockAddr p sa@(SockAddrUnix path) = do
11621149
let pathC = map castCharToCChar path
11631150
-- the buffer is already filled with nulls.
11641151
pokeArray ((#ptr struct sockaddr_un, sun_path) p) pathC
1165-
#else
1166-
pokeSockAddr _ SockAddrUnix{} = error "pokeSockAddr: not supported"
1167-
#endif
11681152
pokeSockAddr p (SockAddrInet port addr) = do
11691153
zeroMemory p (#const sizeof(struct sockaddr_in))
11701154
#if defined(HAVE_STRUCT_SOCKADDR_SA_LEN)
@@ -1189,11 +1173,9 @@ peekSockAddr :: Ptr SockAddr -> IO SockAddr
11891173
peekSockAddr p = do
11901174
family <- (#peek struct sockaddr, sa_family) p
11911175
case family :: CSaFamily of
1192-
#if defined(DOMAIN_SOCKET_SUPPORT)
11931176
(#const AF_UNIX) -> do
11941177
str <- peekCAString ((#ptr struct sockaddr_un, sun_path) p)
11951178
return (SockAddrUnix str)
1196-
#endif
11971179
(#const AF_INET) -> do
11981180
addr <- (#peek struct sockaddr_in, sin_addr) p
11991181
port <- (#peek struct sockaddr_in, sin_port) p

Network/Socket/Unix.hsc

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
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)
1818
import Network.Socket.Buffer
19+
import Network.Socket.Fcntl
1920
import 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
2126
import 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
2333
import Network.Socket.Posix.Cmsg
2434
#endif
25-
import Network.Socket.Types
2635

2736
#if defined(HAVE_GETPEEREID)
2837
import System.IO.Error (catchIOError)
2938
#endif
3039
#ifdef HAVE_GETPEEREID
3140
import 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
4144
import Network.Socket.Options
4245
#endif
@@ -126,11 +129,7 @@ getPeerEid _ = return (0, 0)
126129
--
127130
-- Since 2.7.0.0.
128131
isUnixDomainSocketAvailable :: Bool
129-
#if defined(DOMAIN_SOCKET_SUPPORT)
130132
isUnixDomainSocketAvailable = True
131-
#else
132-
isUnixDomainSocketAvailable = False
133-
#endif
134133

135134
data NullSockAddr = NullSockAddr
136135

@@ -143,33 +142,25 @@ instance SocketAddress NullSockAddr where
143142
-- Use this function in the case where 'isUnixDomainSocketAvailable' is
144143
-- 'True'.
145144
sendFd :: Socket -> CInt -> IO ()
146-
#if defined(DOMAIN_SOCKET_SUPPORT)
147145
sendFd 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'.
161156
recvFd :: Socket -> IO CInt
162-
#if defined(DOMAIN_SOCKET_SUPPORT)
163157
recvFd 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
183188
socketPair 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

195200
foreign import ccall unsafe "socketpair"
196201
c_socketpair :: CInt -> CInt -> CInt -> Ptr CInt -> IO CInt
197-
#else
198-
socketPair _ _ _ = error "Network.Socket.socketPair"
199202
#endif

include/HsNetDef.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
#undef PACKAGE_TARNAME
1111
#undef PACKAGE_VERSION
1212

13-
#define DOMAIN_SOCKET_SUPPORT 1
14-
1513
#if defined(HAVE_STRUCT_UCRED) && HAVE_DECL_SO_PEERCRED
1614
# define HAVE_STRUCT_UCRED_SO_PEERCRED 1
1715
#else

network.cabal

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,9 @@ library
168168
cpp-options: -D_WIN32_WINNT=0x0600
169169
cc-options: -D_WIN32_WINNT=0x0600
170170

171+
build-depends:
172+
temporary
173+
171174
test-suite spec
172175
type: exitcode-stdio-1.0
173176
main-is: Spec.hs

0 commit comments

Comments
 (0)