Skip to content

Commit 25fa2d9

Browse files
Merge pull request #553 from haskell/kazu/unix-domain-for-win
supporting AF_UNIX on Windows
2 parents 956ba0b + 12204c1 commit 25fa2d9

File tree

7 files changed

+40
-21
lines changed

7 files changed

+40
-21
lines changed

Network/Socket/Unix.hsc

+3-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ import System.Posix.Types (Fd(..))
1717

1818
import Network.Socket.Buffer
1919
import Network.Socket.Imports
20-
#if !defined(mingw32_HOST_OS)
20+
#if defined(mingw32_HOST_OS)
21+
import Network.Socket.Win32.Cmsg
22+
#else
2123
import Network.Socket.Posix.Cmsg
2224
#endif
2325
import Network.Socket.Types

Network/Socket/Win32/Cmsg.hsc

+4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ module Network.Socket.Win32.Cmsg where
1212
#include "HsNet.h"
1313

1414
import Data.ByteString.Internal
15+
import System.Posix.Types (Fd(..))
1516
import Foreign.ForeignPtr
1617
import System.IO.Unsafe (unsafeDupablePerformIO)
1718

@@ -191,6 +192,9 @@ instance Storable IPv6PktInfo where
191192
n :: ULONG <- (#peek IN6_PKTINFO, ipi6_ifindex) p
192193
return $ IPv6PktInfo (fromIntegral n) ha6
193194

195+
instance ControlMessage Fd where
196+
controlMessageId = CmsgIdFd
197+
194198
cmsgIdBijection :: Bijection CmsgId String
195199
cmsgIdBijection =
196200
[ (UnsupportedCmsgId, "UnsupportedCmsgId")

include/HsNet.h

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
# include <ws2tcpip.h>
3030
# include <mswsock.h>
3131
# include "win32defs.h"
32+
# include "afunix_compat.h"
3233
# define IPV6_V6ONLY 27
3334
#endif
3435

include/HsNetDef.h

+1-3
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@
1010
#undef PACKAGE_TARNAME
1111
#undef PACKAGE_VERSION
1212

13-
#if !defined(mingw32_HOST_OS) && !defined(_WIN32)
14-
# define DOMAIN_SOCKET_SUPPORT 1
15-
#endif
13+
#define DOMAIN_SOCKET_SUPPORT 1
1614

1715
#if defined(HAVE_STRUCT_UCRED) && HAVE_DECL_SO_PEERCRED
1816
# define HAVE_STRUCT_UCRED_SO_PEERCRED 1

include/afunix_compat.h

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/* The version of afunix.h provided by the version of MSYS2 included with x86
2+
* versions of GHC before GHC 9.2 excludes certain components introduced with
3+
* Windows Vista.
4+
*/
5+
6+
#ifndef AFUNIX_COMPAT_H
7+
#define AFUNIX_COMPAT_H
8+
9+
#if defined(_AFUNIX_) || !defined(_WIN32) || __GLASGOW_HASKELL__ > 902
10+
# include <afunix.h>
11+
#else
12+
13+
#define UNIX_PATH_MAX 108
14+
15+
typedef struct sockaddr_un {
16+
ADDRESS_FAMILY sun_family;
17+
char sun_path[UNIX_PATH_MAX];
18+
} SOCKADDR_UN, *PSOCKADDR_UN;
19+
20+
#define SIO_AF_UNIX_GETPEERPID _WSAIOR(IOC_VENDOR, 256)
21+
22+
#endif /* GHC version check */
23+
#endif /* AFUNIX_COMPAT_H */

network.cabal

+1
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ extra-source-files:
6666
include/HsNetworkConfig.h.in
6767
include/HsNet.h
6868
include/HsNetDef.h
69+
include/afunix_compat.h
6970
cbits/asyncAccept.c
7071
cbits/initWinSock.c
7172
cbits/winSockErr.c

tests/Network/SocketSpec.hs

+7-17
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import Network.Socket
1212
import Network.Socket.ByteString
1313
import Network.Test.Common
1414
import System.Mem (performGC)
15-
import System.IO.Error (tryIOError, isAlreadyInUseError)
15+
import System.IO.Error (tryIOError)
1616
import System.IO.Temp (withSystemTempDirectory)
1717
import Foreign.C.Types ()
1818

@@ -70,9 +70,12 @@ spec = do
7070
bind sock (addrAddress addr) `shouldThrow` anyIOException
7171
#endif
7272

73-
it "successfully binds to a unix socket, twice" $ do
73+
it "successfully binds to a unix socket" $ do
7474
withSystemTempDirectory "haskell-network" $ \path -> do
7575
let sfile = path ++ "/socket-file"
76+
-- exist <- doesFileExist sfile
77+
-- when exist $ removeFile sfile
78+
-- removeFile sfile
7679
let addr = SockAddrUnix sfile
7780
when (isSupportedSockAddr addr) $ do
7881
sock0 <- socket AF_UNIX Stream defaultProtocol
@@ -82,23 +85,10 @@ spec = do
8285
sock1 <- socket AF_UNIX Stream defaultProtocol
8386
tryIOError (bind sock1 addr) >>= \o -> case o of
8487
Right () -> error "bind should have failed but succeeded"
85-
Left e | not (isAlreadyInUseError e) -> ioError e
86-
_ -> return ()
88+
_ -> return ()
8789

8890
close sock0
89-
90-
-- Unix systems tend to leave the file existing, which is
91-
-- why our `bind` does its workaround. however if any
92-
-- system in the future does fix this issue, we don't want
93-
-- this test to fail, since that would defeat the purpose
94-
-- of our workaround. but you can uncomment the below lines
95-
-- if you want to play with this on your own system.
96-
--import System.Directory (doesPathExist)
97-
--ex <- doesPathExist sfile
98-
--unless ex $ error "socket file was deleted unexpectedly"
99-
100-
sock2 <- socket AF_UNIX Stream defaultProtocol
101-
bind sock2 addr
91+
close sock1
10292

10393
describe "UserTimeout" $ do
10494
it "can be set" $ do

0 commit comments

Comments
 (0)