You've already forked wine-staging
mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-04-13 14:42:51 -07:00
Added ws2_32-af_unix patchset
This commit is contained in:
72
patches/ws2_32-af_unix/0001-ws2_32-Add-afunix.h-header.patch
Normal file
72
patches/ws2_32-af_unix/0001-ws2_32-Add-afunix.h-header.patch
Normal file
@@ -0,0 +1,72 @@
|
||||
From 54fc933329986784bb497f24a9ced2f82e9016dd Mon Sep 17 00:00:00 2001
|
||||
From: Ally Sommers <dropbear.sh@gmail.com>
|
||||
Date: Wed, 10 May 2023 09:01:26 -0700
|
||||
Subject: [PATCH] ws2_32: Add afunix.h header.
|
||||
|
||||
This header is needed for support of AF_UNIX sockets.
|
||||
---
|
||||
include/Makefile.in | 1 +
|
||||
include/afunix.h | 38 ++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 39 insertions(+)
|
||||
create mode 100644 include/afunix.h
|
||||
|
||||
diff --git a/include/Makefile.in b/include/Makefile.in
|
||||
index 8d0139d8d21..8eea8049d3e 100644
|
||||
--- a/include/Makefile.in
|
||||
+++ b/include/Makefile.in
|
||||
@@ -12,6 +12,7 @@ SOURCES = \
|
||||
adshlp.h \
|
||||
advpub.h \
|
||||
af_irda.h \
|
||||
+ afunix.h \
|
||||
amaudio.h \
|
||||
amsi.idl \
|
||||
amstream.idl \
|
||||
diff --git a/include/afunix.h b/include/afunix.h
|
||||
new file mode 100644
|
||||
index 00000000000..8118dda271b
|
||||
--- /dev/null
|
||||
+++ b/include/afunix.h
|
||||
@@ -0,0 +1,38 @@
|
||||
+/*
|
||||
+ * Copyright 2023 Ally Sommers
|
||||
+ *
|
||||
+ * This library is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU Lesser General Public
|
||||
+ * License as published by the Free Software Foundation; either
|
||||
+ * version 2.1 of the License, or (at your option) any later version.
|
||||
+ *
|
||||
+ * This library is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * Lesser General Public License for more details.
|
||||
+ *
|
||||
+ * You should have received a copy of the GNU Lesser General Public
|
||||
+ * License along with this library; if not, write to the Free Software
|
||||
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
+ */
|
||||
+
|
||||
+#ifndef _WS2AFUNIX_
|
||||
+#define _WS2AFUNIX_
|
||||
+
|
||||
+#include "windef.h"
|
||||
+#include "ws2def.h"
|
||||
+
|
||||
+#ifdef USE_WS_PREFIX
|
||||
+# define WS(x) WS_##x
|
||||
+#else
|
||||
+# define WS(x) x
|
||||
+#endif
|
||||
+
|
||||
+#define UNIX_PATH_MAX 108
|
||||
+
|
||||
+typedef struct WS(sockaddr_un) {
|
||||
+ USHORT sun_family;
|
||||
+ char sun_path[UNIX_PATH_MAX];
|
||||
+} SOCKADDR_UN, *PSOCKADDR_UN;
|
||||
+
|
||||
+#endif /* _WS2AFUNIX_ */
|
||||
\ No newline at end of file
|
||||
--
|
||||
2.47.2
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,66 @@
|
||||
From 5b0ace840d44ca9072b16b55774c54e6c63d1aa1 Mon Sep 17 00:00:00 2001
|
||||
From: Ally Sommers <dropbear.sh@gmail.com>
|
||||
Date: Thu, 30 Jan 2025 23:48:43 +0100
|
||||
Subject: [PATCH] server: Allow for deletion of socket files.
|
||||
|
||||
Deleting the socket file is a common pattern with AF_UNIX sockets, and
|
||||
is analogous to unbinding.
|
||||
---
|
||||
server/fd.c | 30 +++++++++++++++++++++++++++---
|
||||
1 file changed, 27 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/server/fd.c b/server/fd.c
|
||||
index 313220b5aaf..c42a701890e 100644
|
||||
--- a/server/fd.c
|
||||
+++ b/server/fd.c
|
||||
@@ -2077,6 +2077,19 @@ struct fd *open_fd( struct fd *root, const char *name, struct unicode_str nt_nam
|
||||
fd->unix_fd = open( name, O_RDONLY | (flags & ~(O_TRUNC | O_CREAT | O_EXCL)), *mode );
|
||||
}
|
||||
|
||||
+ /* POSIX requires that open(2) throws EOPNOTSUPP when `path` is a Unix
|
||||
+ * socket. *BSD throws EOPNOTSUPP in this case and the additional case of
|
||||
+ * O_SHLOCK or O_EXLOCK being passed when `path` resides on a filesystem
|
||||
+ * without lock support.
|
||||
+ *
|
||||
+ * Contrary to POSIX, Linux returns ENXIO in this case, so we also check
|
||||
+ * that error code here. */
|
||||
+ if (errno == EOPNOTSUPP || errno == ENXIO)
|
||||
+ {
|
||||
+ if (!stat(name, &st) && S_ISSOCK(st.st_mode) && (options & FILE_DELETE_ON_CLOSE))
|
||||
+ goto skip_open_fail;
|
||||
+ }
|
||||
+
|
||||
if (fd->unix_fd == -1)
|
||||
{
|
||||
/* check for trailing slash on file path */
|
||||
@@ -2088,13 +2101,24 @@ struct fd *open_fd( struct fd *root, const char *name, struct unicode_str nt_nam
|
||||
}
|
||||
}
|
||||
|
||||
+skip_open_fail:
|
||||
fd->nt_name = dup_nt_name( root, nt_name, &fd->nt_namelen );
|
||||
fd->unix_name = NULL;
|
||||
- fstat( fd->unix_fd, &st );
|
||||
+ if ((path = dup_fd_name( root, name )))
|
||||
+ {
|
||||
+ fd->unix_name = realpath( path, NULL );
|
||||
+ free( path );
|
||||
+ }
|
||||
+
|
||||
+ closed_fd->unix_fd = fd->unix_fd;
|
||||
+ closed_fd->disp_flags = 0;
|
||||
+ closed_fd->unix_name = fd->unix_name;
|
||||
+ if (fd->unix_fd != -1)
|
||||
+ fstat( fd->unix_fd, &st );
|
||||
*mode = st.st_mode;
|
||||
|
||||
- /* only bother with an inode for normal files and directories */
|
||||
- if (S_ISREG(st.st_mode) || S_ISDIR(st.st_mode) || S_ISLNK(st.st_mode))
|
||||
+ /* only bother with an inode for normal files, directories, and socket files */
|
||||
+ if (S_ISREG(st.st_mode) || S_ISDIR(st.st_mode) || S_ISSOCK(st.st_mode))
|
||||
{
|
||||
unsigned int err;
|
||||
struct inode *inode = get_inode( st.st_dev, st.st_ino, fd->unix_fd );
|
||||
--
|
||||
2.47.2
|
||||
|
@@ -0,0 +1,30 @@
|
||||
From 29a79759aa334517dee63d5e6acfeb10777f6215 Mon Sep 17 00:00:00 2001
|
||||
From: Ally Sommers <dropbear.sh@gmail.com>
|
||||
Date: Tue, 16 May 2023 02:20:55 -0700
|
||||
Subject: [PATCH] server: Introduce error when attempting to create a
|
||||
SOCK_DGRAM AF_UNIX socket.
|
||||
|
||||
---
|
||||
server/sock.c | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/server/sock.c b/server/sock.c
|
||||
index 8262898c436..67b84346ab4 100644
|
||||
--- a/server/sock.c
|
||||
+++ b/server/sock.c
|
||||
@@ -1897,6 +1897,12 @@ static int init_socket( struct sock *sock, int family, int type, int protocol )
|
||||
return -1;
|
||||
}
|
||||
|
||||
+ if (unix_family == AF_UNIX && unix_type == SOCK_DGRAM)
|
||||
+ {
|
||||
+ set_win32_error(WSAEAFNOSUPPORT);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
sockfd = socket( unix_family, unix_type, unix_protocol );
|
||||
|
||||
#ifdef linux
|
||||
--
|
||||
2.47.2
|
||||
|
@@ -0,0 +1,111 @@
|
||||
From d48d02fa64e9925e275307df793b09e91f3fa71f Mon Sep 17 00:00:00 2001
|
||||
From: Ally Sommers <dropbear.sh@gmail.com>
|
||||
Date: Wed, 7 Jun 2023 00:30:53 -0700
|
||||
Subject: [PATCH] server: Fix getsockname() and accept() on AF_UNIX sockets.
|
||||
|
||||
---
|
||||
server/sock.c | 72 ++++++++++++++++++++++++++++++++++++++++++---------
|
||||
1 file changed, 60 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/server/sock.c b/server/sock.c
|
||||
index 67b84346ab4..ea5948abd16 100644
|
||||
--- a/server/sock.c
|
||||
+++ b/server/sock.c
|
||||
@@ -2083,11 +2083,32 @@ static struct sock *accept_socket( struct sock *sock )
|
||||
unix_len = sizeof(unix_addr);
|
||||
if (!getsockname( acceptfd, &unix_addr.addr, &unix_len ))
|
||||
{
|
||||
- acceptsock->addr_len = sockaddr_from_unix( &unix_addr, &acceptsock->addr.addr, sizeof(acceptsock->addr) );
|
||||
+ if (sock->family == WS_AF_UNIX)
|
||||
+ {
|
||||
+ acceptsock->addr_len = sock->addr_len;
|
||||
+ acceptsock->addr.un = sock->addr.un;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ acceptsock->addr_len = sockaddr_from_unix( &unix_addr,
|
||||
+ &acceptsock->addr.addr,
|
||||
+ sizeof(acceptsock->addr) );
|
||||
+ }
|
||||
+
|
||||
if (!getpeername( acceptfd, &unix_addr.addr, &unix_len ))
|
||||
- acceptsock->peer_addr_len = sockaddr_from_unix( &unix_addr,
|
||||
- &acceptsock->peer_addr.addr,
|
||||
- sizeof(acceptsock->peer_addr) );
|
||||
+ {
|
||||
+ if (sock->family == WS_AF_UNIX)
|
||||
+ {
|
||||
+ acceptsock->peer_addr_len = sizeof( sock->peer_addr.un );
|
||||
+ acceptsock->peer_addr.un = sock->peer_addr.un;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ acceptsock->peer_addr_len = sockaddr_from_unix( &unix_addr,
|
||||
+ &acceptsock->peer_addr.addr,
|
||||
+ sizeof(acceptsock->peer_addr) );
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2147,11 +2168,31 @@ static int accept_into_socket( struct sock *sock, struct sock *acceptsock )
|
||||
unix_len = sizeof(unix_addr);
|
||||
if (!getsockname( get_unix_fd( newfd ), &unix_addr.addr, &unix_len ))
|
||||
{
|
||||
- acceptsock->addr_len = sockaddr_from_unix( &unix_addr, &acceptsock->addr.addr, sizeof(acceptsock->addr) );
|
||||
+ if (sock->family == WS_AF_UNIX)
|
||||
+ {
|
||||
+ acceptsock->addr_len = sock->addr_len;
|
||||
+ acceptsock->addr.un = sock->addr.un;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ acceptsock->addr_len = sockaddr_from_unix( &unix_addr,
|
||||
+ &acceptsock->addr.addr,
|
||||
+ sizeof(acceptsock->addr) );
|
||||
+ }
|
||||
if (!getpeername( get_unix_fd( newfd ), &unix_addr.addr, &unix_len ))
|
||||
- acceptsock->peer_addr_len = sockaddr_from_unix( &unix_addr,
|
||||
- &acceptsock->peer_addr.addr,
|
||||
- sizeof(acceptsock->peer_addr) );
|
||||
+ {
|
||||
+ if (sock->family == WS_AF_UNIX)
|
||||
+ {
|
||||
+ acceptsock->peer_addr_len = sizeof( sock->peer_addr.un );
|
||||
+ acceptsock->peer_addr.un = sock->peer_addr.un;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ acceptsock->peer_addr_len = sockaddr_from_unix( &unix_addr,
|
||||
+ &acceptsock->peer_addr.addr,
|
||||
+ sizeof(acceptsock->peer_addr) );
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
clear_error();
|
||||
@@ -2787,10 +2828,17 @@ static void sock_ioctl( struct fd *fd, ioctl_code_t code, struct async *async )
|
||||
allow_fd_caching( sock->fd );
|
||||
|
||||
unix_len = sizeof(unix_addr);
|
||||
- getsockname( unix_fd, &unix_addr.addr, &unix_len );
|
||||
- sock->addr_len = sockaddr_from_unix( &unix_addr, &sock->addr.addr, sizeof(sock->addr) );
|
||||
- sock->peer_addr_len = sockaddr_from_unix( &peer_addr, &sock->peer_addr.addr, sizeof(sock->peer_addr));
|
||||
-
|
||||
+ if (sock->family == WS_AF_UNIX)
|
||||
+ {
|
||||
+ sock->peer_addr.un = *(struct WS_sockaddr_un *)addr;
|
||||
+ sock->peer_addr_len = sizeof(struct WS_sockaddr_un);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ getsockname( unix_fd, &unix_addr.addr, &unix_len );
|
||||
+ sock->addr_len = sockaddr_from_unix( &unix_addr, &sock->addr.addr, sizeof(sock->addr) );
|
||||
+ sock->peer_addr_len = sockaddr_from_unix( &peer_addr, &sock->peer_addr.addr, sizeof(sock->peer_addr));
|
||||
+ }
|
||||
sock->bound = 1;
|
||||
|
||||
if (!ret)
|
||||
--
|
||||
2.47.2
|
||||
|
@@ -0,0 +1,330 @@
|
||||
From 87f55f51f9985ed20a718d1db3a440b30376bbf3 Mon Sep 17 00:00:00 2001
|
||||
From: Ally Sommers <dropbear.sh@gmail.com>
|
||||
Date: Thu, 30 Jan 2025 23:50:25 +0100
|
||||
Subject: [PATCH] ws2_32/tests: Add test for AF_UNIX sockets.
|
||||
|
||||
Bug: https://bugs.winehq.org/show_bug.cgi?id=52568
|
||||
---
|
||||
dlls/ws2_32/tests/sock.c | 292 +++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 292 insertions(+)
|
||||
|
||||
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
|
||||
index 4fd5fc00cdd..510cbfc17f5 100644
|
||||
--- a/dlls/ws2_32/tests/sock.c
|
||||
+++ b/dlls/ws2_32/tests/sock.c
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <iphlpapi.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <wsipx.h>
|
||||
+#include <afunix.h>
|
||||
#include <wsnwlink.h>
|
||||
#include <mswsock.h>
|
||||
#include <mstcpip.h>
|
||||
@@ -14373,6 +14374,296 @@ static void test_send_buffering(void)
|
||||
closesocket(client);
|
||||
}
|
||||
|
||||
+static void test_afunix(void)
|
||||
+{
|
||||
+ SOCKET listener, client, server = 0;
|
||||
+ SOCKADDR_UN addr = { AF_UNIX, "test_afunix.sock" };
|
||||
+ char serverBuf[] = "ws2_32/AF_UNIX socket test";
|
||||
+ char clientBuf[sizeof(serverBuf)] = { 0 };
|
||||
+
|
||||
+ char paths[4][sizeof(addr.sun_path)] = { "./tmp.sock", "../tmp.sock" };
|
||||
+ char dosPath[sizeof(addr.sun_path)];
|
||||
+ WCHAR dosWidePath[sizeof(addr.sun_path)];
|
||||
+ UNICODE_STRING ntPath = { 0 };
|
||||
+ SOCKADDR_UN outAddr = { 0 };
|
||||
+ int outAddrSize = sizeof(outAddr);
|
||||
+ SOCKADDR_UN truncatedAddr = { 0 };
|
||||
+ ULONG zero = 0;
|
||||
+ ULONG one = 1;
|
||||
+ int ret;
|
||||
+
|
||||
+ /* Test connection and send/recv */
|
||||
+ listener = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
+ if (listener == INVALID_SOCKET && GetLastError() == WSAEAFNOSUPPORT)
|
||||
+ {
|
||||
+ win_skip("AF_UNIX sockets are unsupported, skipping...\n");
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ ok(listener != INVALID_SOCKET, "Could not create Unix socket: %lu\n",
|
||||
+ GetLastError());
|
||||
+
|
||||
+ ret = bind(listener, (SOCKADDR *)&addr, 0);
|
||||
+ ok(ret && GetLastError() == WSAEFAULT, "Incorrect error: %lu\n", GetLastError());
|
||||
+ ret = bind(listener, (SOCKADDR *)&addr, 2);
|
||||
+ ok(!ret, "Could not bind Unix socket: %lu\n", GetLastError());
|
||||
+ ret = listen(listener, 1);
|
||||
+ ok(!ret, "Could not listen on Unix socket: %lu\n", GetLastError());
|
||||
+ closesocket(listener);
|
||||
+
|
||||
+ listener = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
+ ok(listener != INVALID_SOCKET, "Could not create Unix socket: %lu\n",
|
||||
+ GetLastError());
|
||||
+ ret = bind(listener, (SOCKADDR *)&addr, 3);
|
||||
+ ok(!ret, "Could not bind Unix socket: %lu\n", GetLastError());
|
||||
+
|
||||
+ memcpy(&truncatedAddr, &addr, 3);
|
||||
+ ret = getsockname(listener, (SOCKADDR *)&outAddr, &outAddrSize);
|
||||
+ ok(!ret, "Could not get info on Unix socket: %lu\n", GetLastError());
|
||||
+ ok(!memcmp(truncatedAddr.sun_path, outAddr.sun_path, sizeof(addr.sun_path)),
|
||||
+ "getsockname returned incorrect path '%s' for provided path '%s'\n",
|
||||
+ outAddr.sun_path,
|
||||
+ truncatedAddr.sun_path);
|
||||
+ ok(outAddrSize == sizeof(outAddr.sun_family) + strlen(outAddr.sun_path) + 1,
|
||||
+ "getsockname returned incorrect size '%d' for provided path '%s'\n",
|
||||
+ outAddrSize,
|
||||
+ truncatedAddr.sun_path);
|
||||
+ closesocket(listener);
|
||||
+ ret = DeleteFileA(truncatedAddr.sun_path);
|
||||
+ ok(ret, "DeleteFileA on socket file failed: %lu\n", GetLastError());
|
||||
+ ok(GetFileAttributesA(truncatedAddr.sun_path) == INVALID_FILE_ATTRIBUTES &&
|
||||
+ GetLastError() == ERROR_FILE_NOT_FOUND,
|
||||
+ "Failed to delete socket file at path '%s'\n",
|
||||
+ truncatedAddr.sun_path);
|
||||
+
|
||||
+ listener = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
+ ok(listener != INVALID_SOCKET, "Could not create Unix socket: %lu\n",
|
||||
+ GetLastError());
|
||||
+
|
||||
+ ret = bind(listener, (SOCKADDR *)&addr, sizeof(SOCKADDR_UN));
|
||||
+ ok(!ret, "Could not bind Unix socket: %lu\n", GetLastError());
|
||||
+
|
||||
+ ret = listen(listener, 1);
|
||||
+ ok(!ret, "Could not listen on Unix socket: %lu\n", GetLastError());
|
||||
+
|
||||
+ client = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
+ ok(client != INVALID_SOCKET, "Failed to create second Unix socket: %lu\n",
|
||||
+ GetLastError());
|
||||
+
|
||||
+ ret = ioctlsocket(client, FIONBIO, &one);
|
||||
+ ok(!ret, "Could not set AF_UNIX socket to nonblocking: %lu; skipping connection\n", GetLastError());
|
||||
+ if (!ret)
|
||||
+ {
|
||||
+ ret = connect(client, (SOCKADDR *)&addr, sizeof(addr));
|
||||
+ ok(!ret || (ret == SOCKET_ERROR && GetLastError() == WSAEWOULDBLOCK),
|
||||
+ "Error when connecting to Unix socket: %lu\n",
|
||||
+ GetLastError());
|
||||
+ server = accept(listener, NULL, NULL);
|
||||
+ ok(server != INVALID_SOCKET, "Could not accept Unix socket connection: %lu\n",
|
||||
+ GetLastError());
|
||||
+ ret = ioctlsocket(client, FIONBIO, &zero);
|
||||
+ ok(!ret, "Could not set AF_UNIX socket to blocking: %lu\n", GetLastError());
|
||||
+ }
|
||||
+
|
||||
+ ret = send(server, serverBuf, sizeof(serverBuf), 0);
|
||||
+ ok(ret == sizeof(serverBuf), "Incorrect return value from send: %d\n", ret);
|
||||
+ ret = recv(client, clientBuf, sizeof(serverBuf), 0);
|
||||
+ ok(ret == sizeof(serverBuf), "Incorrect return value from recv: %d\n", ret);
|
||||
+ ok(!memcmp(serverBuf, clientBuf, sizeof(serverBuf)), "Data mismatch over Unix socket\n");
|
||||
+
|
||||
+ memset(clientBuf, 0, sizeof(clientBuf));
|
||||
+
|
||||
+ ret = sendto(server, serverBuf, sizeof(serverBuf), 0, NULL, 0);
|
||||
+ ok(ret == sizeof(serverBuf), "Incorrect return value from sendto: %d\n", ret);
|
||||
+ ret = recvfrom(client, clientBuf, sizeof(serverBuf), 0, NULL, 0);
|
||||
+ ok(ret == sizeof(serverBuf), "Incorrect return value from recvfrom: %d\n", ret);
|
||||
+ ok(!memcmp(serverBuf, clientBuf, sizeof(serverBuf)), "Data mismatch over Unix socket\n");
|
||||
+
|
||||
+ memset(serverBuf, 0, sizeof(serverBuf));
|
||||
+
|
||||
+ ret = send(client, clientBuf, sizeof(clientBuf), 0);
|
||||
+ ok(ret == sizeof(clientBuf), "Incorrect return value from send: %d\n", ret);
|
||||
+ ret = recv(server, serverBuf, sizeof(clientBuf), 0);
|
||||
+ ok(ret == sizeof(serverBuf), "Incorrect return value from recv: %d\n", ret);
|
||||
+ ok(!memcmp(serverBuf, clientBuf, sizeof(clientBuf)), "Data mismatch over Unix socket\n");
|
||||
+
|
||||
+ memset(serverBuf, 0, sizeof(serverBuf));
|
||||
+
|
||||
+ ret = sendto(client, clientBuf, sizeof(clientBuf), 0, NULL, 0);
|
||||
+ ok(ret == sizeof(clientBuf), "Incorrect return value from sendto: %d\n", ret);
|
||||
+ ret = recvfrom(server, serverBuf, sizeof(clientBuf), 0, NULL, 0);
|
||||
+ ok(ret == sizeof(serverBuf), "Incorrect return value from recvfrom: %d\n", ret);
|
||||
+ ok(!memcmp(serverBuf, clientBuf, sizeof(clientBuf)), "Data mismatch over Unix socket\n");
|
||||
+
|
||||
+ closesocket(listener);
|
||||
+ closesocket(client);
|
||||
+ closesocket(server);
|
||||
+
|
||||
+ /* Test socket file deletion */
|
||||
+ ret = DeleteFileA("test_afunix.sock");
|
||||
+ ok(ret, "DeleteFileA on socket file failed: %lu\n", GetLastError());
|
||||
+ ok(GetFileAttributesA("test_afunix.sock") == INVALID_FILE_ATTRIBUTES &&
|
||||
+ GetLastError() == ERROR_FILE_NOT_FOUND,
|
||||
+ "Failed to delete socket file at path '%s'\n",
|
||||
+ addr.sun_path);
|
||||
+
|
||||
+ /* Test failure modes */
|
||||
+ listener = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
+ ok(listener != INVALID_SOCKET, "Could not create Unix socket: %lu\n",
|
||||
+ GetLastError());
|
||||
+ ret = bind(listener, (SOCKADDR *)&addr, sizeof(SOCKADDR_UN));
|
||||
+ ok(!ret, "Could not bind Unix socket to path '%s': %lu\n", addr.sun_path, GetLastError());
|
||||
+ closesocket(listener);
|
||||
+ listener = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
+ ok(listener != INVALID_SOCKET, "Could not create Unix socket: %lu\n",
|
||||
+ GetLastError());
|
||||
+ ret = bind(listener, (SOCKADDR *)&addr, sizeof(SOCKADDR_UN));
|
||||
+ ok(ret && GetLastError() == WSAEADDRINUSE,
|
||||
+ "Bound Unix socket to path '%s' despite existing socket file: %lu\n",
|
||||
+ addr.sun_path,
|
||||
+ GetLastError());
|
||||
+ closesocket(listener);
|
||||
+ ret = DeleteFileA(addr.sun_path);
|
||||
+ ok(ret, "DeleteFileA on socket file failed: %lu\n", GetLastError());
|
||||
+ ok(GetFileAttributesA("test_afunix.sock") == INVALID_FILE_ATTRIBUTES &&
|
||||
+ GetLastError() == ERROR_FILE_NOT_FOUND,
|
||||
+ "Failed to delete socket file at path '%s'\n",
|
||||
+ addr.sun_path);
|
||||
+
|
||||
+ /* Test different path types (relative, NT, etc.) */
|
||||
+ GetTempPathA(sizeof(paths[0]) - 1, paths[2]);
|
||||
+ strcat(paths[2], "tmp.sock");
|
||||
+ MultiByteToWideChar(CP_ACP, 0, paths[2], -1, dosWidePath, sizeof(dosPath));
|
||||
+ RtlDosPathNameToNtPathName_U(dosWidePath, &ntPath, NULL, NULL);
|
||||
+ RtlUnicodeToMultiByteN(paths[3], sizeof(addr.sun_path) - 1, NULL, ntPath.Buffer, ntPath.Length);
|
||||
+
|
||||
+ for (int i = 0; i < sizeof(paths) / sizeof(paths[0]); i++)
|
||||
+ {
|
||||
+ memcpy(addr.sun_path, paths[i], sizeof(paths[i]));
|
||||
+
|
||||
+ listener = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
+ ok(listener != INVALID_SOCKET, "Could not create Unix socket: %lu\n",
|
||||
+ GetLastError());
|
||||
+
|
||||
+ ret = bind(listener, (SOCKADDR *)&addr, sizeof(SOCKADDR_UN));
|
||||
+ ok(!ret, "Could not bind Unix socket to path '%s': %lu\n", addr.sun_path, GetLastError());
|
||||
+
|
||||
+ ret = listen(listener, 1);
|
||||
+ ok(!ret, "Could not listen on Unix socket: %lu\n", GetLastError());
|
||||
+
|
||||
+ client = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
+ ok(client != INVALID_SOCKET, "Failed to create second Unix socket: %lu\n",
|
||||
+ GetLastError());
|
||||
+
|
||||
+ ret = ioctlsocket(client, FIONBIO, &one);
|
||||
+ ok(!ret, "Could not set AF_UNIX socket to nonblocking: %lu; skipping connection\n", GetLastError());
|
||||
+ if (!ret)
|
||||
+ {
|
||||
+ ret = connect(client, (SOCKADDR *)&addr, sizeof(addr));
|
||||
+ ok(!ret || (ret == SOCKET_ERROR && GetLastError() == WSAEWOULDBLOCK),
|
||||
+ "Error when connecting to Unix socket: %lu\n",
|
||||
+ GetLastError());
|
||||
+ server = accept(listener, NULL, NULL);
|
||||
+ ok(server != INVALID_SOCKET, "Could not accept Unix socket connection: %lu\n",
|
||||
+ GetLastError());
|
||||
+ ret = ioctlsocket(client, FIONBIO, &zero);
|
||||
+ ok(!ret, "Could not set AF_UNIX socket to blocking: %lu\n", GetLastError());
|
||||
+ }
|
||||
+
|
||||
+ memset(&outAddr, 0, sizeof(outAddr));
|
||||
+ outAddrSize = sizeof(outAddr);
|
||||
+ ret = getsockname(listener, (SOCKADDR *)&outAddr, &outAddrSize);
|
||||
+ ok(!ret, "Could not get info on Unix socket: %lu\n", GetLastError());
|
||||
+ ok(!memcmp(addr.sun_path, outAddr.sun_path, sizeof(addr.sun_path)),
|
||||
+ "getsockname returned incorrect path '%s' for provided path '%s'\n",
|
||||
+ outAddr.sun_path,
|
||||
+ addr.sun_path);
|
||||
+ ok(outAddrSize == sizeof(outAddr.sun_family) + strlen(outAddr.sun_path) + 1,
|
||||
+ "getsockname returned incorrect size '%d' for provided path '%s'\n",
|
||||
+ outAddrSize,
|
||||
+ addr.sun_path);
|
||||
+
|
||||
+ memset(&outAddr, 0, sizeof(outAddr));
|
||||
+ outAddrSize = sizeof(outAddr);
|
||||
+ ret = getsockname(client, (SOCKADDR *)&outAddr, &outAddrSize);
|
||||
+ ok(!ret, "Could not get info on Unix socket: %lu\n", GetLastError());
|
||||
+ ok(!memcmp((char[108]){0}, outAddr.sun_path, sizeof(addr.sun_path)),
|
||||
+ "getsockname returned incorrect path '%s' for provided path '%s'\n",
|
||||
+ outAddr.sun_path,
|
||||
+ addr.sun_path);
|
||||
+ ok(outAddrSize == sizeof(outAddr),
|
||||
+ "getsockname returned incorrect size '%d' for provided path '%s'\n",
|
||||
+ outAddrSize,
|
||||
+ addr.sun_path);
|
||||
+
|
||||
+ memset(&outAddr, 0, sizeof(outAddr));
|
||||
+ outAddrSize = sizeof(outAddr);
|
||||
+ ret = getsockname(server, (SOCKADDR *)&outAddr, &outAddrSize);
|
||||
+ ok(!ret, "Could not get info on Unix socket: %lu\n", GetLastError());
|
||||
+ ok(!memcmp(addr.sun_path, outAddr.sun_path, sizeof(addr.sun_path)),
|
||||
+ "getsockname returned incorrect path '%s' for provided path '%s'\n",
|
||||
+ outAddr.sun_path,
|
||||
+ addr.sun_path);
|
||||
+ ok(outAddrSize == sizeof(outAddr.sun_family) + strlen(outAddr.sun_path) + 1,
|
||||
+ "getsockname returned incorrect size '%d' for provided path '%s'\n",
|
||||
+ outAddrSize,
|
||||
+ addr.sun_path);
|
||||
+
|
||||
+ memset(&outAddr, 0, sizeof(outAddr));
|
||||
+ outAddrSize = sizeof(outAddr);
|
||||
+ ret = getpeername(listener, (SOCKADDR *)&outAddr, &outAddrSize);
|
||||
+ ok(ret == -1, "Got info on Unix socket: %lu\n", GetLastError());
|
||||
+ ok(GetLastError() == WSAENOTCONN,
|
||||
+ "Incorrect error returned from getpeername on Unix socket: %ld\n",
|
||||
+ GetLastError());
|
||||
+ ok(!memcmp((char[108]){0}, outAddr.sun_path, sizeof(addr.sun_path)),
|
||||
+ "getpeername returned incorrect path '%s' for provided path '%s'\n",
|
||||
+ outAddr.sun_path,
|
||||
+ addr.sun_path);
|
||||
+ ok(outAddrSize == sizeof(outAddr),
|
||||
+ "getpeername returned incorrect size '%d' for provided path '%s'\n",
|
||||
+ outAddrSize,
|
||||
+ addr.sun_path);
|
||||
+
|
||||
+ memset(&outAddr, 0, sizeof(outAddr));
|
||||
+ outAddrSize = sizeof(outAddr);
|
||||
+ ret = getpeername(client, (SOCKADDR *)&outAddr, &outAddrSize);
|
||||
+ ok(!ret, "Could not get info on Unix socket: %lu\n", GetLastError());
|
||||
+ ok(!memcmp(addr.sun_path, outAddr.sun_path, sizeof(addr.sun_path)),
|
||||
+ "getpeername returned incorrect path '%s' for provided path '%s'\n",
|
||||
+ outAddr.sun_path,
|
||||
+ addr.sun_path);
|
||||
+ ok(outAddrSize == sizeof(outAddr),
|
||||
+ "getpeername returned incorrect size '%d' for provided path '%s'\n",
|
||||
+ outAddrSize,
|
||||
+ addr.sun_path);
|
||||
+
|
||||
+ memset(&outAddr, 0, sizeof(outAddr));
|
||||
+ outAddrSize = sizeof(outAddr);
|
||||
+ ret = getpeername(server, (SOCKADDR *)&outAddr, &outAddrSize);
|
||||
+ ok(!ret, "Could not get info on Unix socket: %lu\n", GetLastError());
|
||||
+ ok(!memcmp((char[108]){0}, outAddr.sun_path, sizeof(addr.sun_path)),
|
||||
+ "getpeername returned incorrect path '%s' for provided path '%s'\n",
|
||||
+ outAddr.sun_path,
|
||||
+ addr.sun_path);
|
||||
+ ok(outAddrSize == sizeof(outAddr),
|
||||
+ "getpeername returned incorrect size '%d' for provided path '%s'\n",
|
||||
+ outAddrSize,
|
||||
+ addr.sun_path);
|
||||
+
|
||||
+ closesocket(listener);
|
||||
+ closesocket(client);
|
||||
+ closesocket(server);
|
||||
+
|
||||
+ ret = DeleteFileA(addr.sun_path);
|
||||
+ ok(ret, "DeleteFileA on socket file failed: %lu\n", GetLastError());
|
||||
+ ok(GetFileAttributesA(addr.sun_path) == INVALID_FILE_ATTRIBUTES &&
|
||||
+ GetLastError() == ERROR_FILE_NOT_FOUND,
|
||||
+ "Failed to delete socket file at path '%s'\n",
|
||||
+ addr.sun_path);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
START_TEST( sock )
|
||||
{
|
||||
int i;
|
||||
@@ -14457,6 +14748,7 @@ START_TEST( sock )
|
||||
test_tcp_sendto_recvfrom();
|
||||
test_broadcast();
|
||||
test_send_buffering();
|
||||
+ test_afunix();
|
||||
|
||||
/* There is apparently an obscure interaction between this test and
|
||||
* test_WSAGetOverlappedResult().
|
||||
--
|
||||
2.47.2
|
||||
|
1
patches/ws2_32-af_unix/definition
Normal file
1
patches/ws2_32-af_unix/definition
Normal file
@@ -0,0 +1 @@
|
||||
Fixes: [52568] ws_ws2: Support for AF_UNIX sockets.
|
Reference in New Issue
Block a user