Skip to content

Commit 27d9815

Browse files
committed
Supporting socket2fd on Windows
Credit: Tamar Christina <[email protected]>
1 parent d0bba03 commit 27d9815

File tree

3 files changed

+36
-0
lines changed

3 files changed

+36
-0
lines changed

Network/Socket/Types.hsc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,16 @@ withFdSocket (Socket ref _) f = do
174174
-- duplicated file descriptor.
175175
socketToFd :: Socket -> IO CInt
176176
socketToFd s = do
177+
#if defined(mingw32_HOST_OS)
178+
fd <- unsafeFdSocket s
179+
fd2 <- c_wsaDuplicate fd
180+
-- FIXME: throw error no if -1
181+
close s
182+
return fd2
183+
184+
foreign import ccall unsafe "wsaDuplicate"
185+
c_wsaDuplicate :: CInt -> IO CInt
186+
#else
177187
fd <- unsafeFdSocket s
178188
-- FIXME: throw error no if -1
179189
fd2 <- c_dup fd
@@ -182,6 +192,7 @@ socketToFd s = do
182192

183193
foreign import ccall unsafe "dup"
184194
c_dup :: CInt -> IO CInt
195+
#endif
185196

186197
-- | Creating a socket from a file descriptor.
187198
mkSocket :: CInt -> IO Socket

cbits/initWinSock.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,4 +40,19 @@ initWinSock ()
4040
return 0;
4141
}
4242

43+
SOCKET
44+
wsaDuplicate (SOCKET s)
45+
{
46+
WSAPROTOCOL_INFOW protocolInfo;
47+
if (WSADuplicateSocketW (s, GetCurrentProcessId (), &protocolInfo) != 0)
48+
return -1;
49+
50+
SOCKET res = WSASocketW(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,
51+
FROM_PROTOCOL_INFO, &protocolInfo, 0, 0);
52+
if (res == SOCKET_ERROR)
53+
return -1;
54+
55+
return res;
56+
}
57+
4358
#endif

tests/Network/SocketSpec.hs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,3 +209,13 @@ spec = do
209209
threadDelay 10000
210210
void $ recv sock 1024
211211
tcpTest client server
212+
213+
describe "socketToFd" $ do
214+
it "socketToFd can send using fd" $ do
215+
let server sock = do
216+
void $ recv sock 1024
217+
client sock = do
218+
fd <- socketToFd sock
219+
s <- mkSocket fd
220+
sendAll s "HELLO WORLD"
221+
tcpTest client server

0 commit comments

Comments
 (0)