Any comments on this one?
I previously posted a slightly different version: https://www.winehq.org/pipermail/wine-devel/2020-August/172582.html
This version of the patch only changes the memcpy and memcmp calls so that we don't assume UNIX_PATH_MAX is always 108 bytes (on MacOS it's 104 bytes). I'm unable to test this on MacOS.
On Linux I have tested this pretty extensively using nbdkit, our Network Block Device server, cross-compiled with mingw-w64 and running under Wine from git with this patch. https://github.com/libguestfs/nbdkit
Rich.
This is the most minimal support for AF_UNIX. Windows 10 has had AF_UNIX support for a while: https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/
Signed-off-by: Richard W.M. Jones rjones@redhat.com --- dlls/ws2_32/socket.c | 34 ++++++++++++++++++++++++++++++++++ include/Makefile.in | 1 + include/afunix.h | 43 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 4d2afa946b..b6378133db 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -132,6 +132,8 @@ # include <sys/time.h> #endif
+#include <sys/un.h> + #define NONAMELESSUNION #define NONAMELESSSTRUCT #include "ntstatus.h" @@ -151,6 +153,7 @@ #include "wshisotp.h" #include "mstcpip.h" #include "af_irda.h" +#include "afunix.h" #include "winnt.h" #define USE_WC_PREFIX /* For CMSG_DATA */ #include "iphlpapi.h" @@ -745,6 +748,7 @@ static const int ws_ipv6_map[][2] = static const int ws_af_map[][2] = { MAP_OPTION( AF_UNSPEC ), + MAP_OPTION( AF_UNIX ), MAP_OPTION( AF_INET ), MAP_OPTION( AF_INET6 ), #ifdef HAS_IPX @@ -1802,6 +1806,7 @@ static inline BOOL supported_pf(int pf) { switch (pf) { + case WS_AF_UNIX: case WS_AF_INET: case WS_AF_INET6: return TRUE; @@ -1900,6 +1905,18 @@ static unsigned int ws_sockaddr_ws2u(const struct WS_sockaddr* wsaddr, int wsadd memcpy(&uin->sin_addr,&win->sin_addr,4); /* 4 bytes = 32 address bits */ break; } + case WS_AF_UNIX: { + struct sockaddr_un* un = (struct sockaddr_un *)uaddr; + const struct WS_sockaddr_un* wun = (const struct WS_sockaddr_un*)wsaddr; + + if (wsaddrlen<sizeof(struct WS_sockaddr_un)) + return 0; + uaddrlen = sizeof(struct sockaddr_un); + memset( uaddr, 0, uaddrlen ); + un->sun_family = AF_UNIX; + memcpy(&un->sun_path, &wun->sun_path, sizeof(un->sun_path)); + break; + } #ifdef HAS_IRDA case WS_AF_IRDA: { struct sockaddr_irda *uin = (struct sockaddr_irda *)uaddr; @@ -1984,6 +2001,12 @@ static BOOL is_sockaddr_bound(const struct sockaddr *uaddr, int uaddrlen) const struct sockaddr_in *in = (const struct sockaddr_in*) uaddr; return in->sin_port || memcmp(&in->sin_addr, &emptyAddr.sin_addr, sizeof(struct in_addr)); } + case AF_UNIX: + { + static const struct sockaddr_un emptyAddr; + const struct sockaddr_un *un = (const struct sockaddr_un*) uaddr; + return memcmp(&un->sun_path, &emptyAddr.sun_path, sizeof(un->sun_path)); + } case AF_UNSPEC: return FALSE; default: @@ -2108,6 +2131,17 @@ static int ws_sockaddr_u2ws(const struct sockaddr* uaddr, struct WS_sockaddr* ws *wsaddrlen = sizeof(struct WS_sockaddr_in); return 0; } + case AF_UNIX: { + const struct sockaddr_un* un = (const struct sockaddr_un*)uaddr; + struct WS_sockaddr_un* wun = (struct WS_sockaddr_un*)wsaddr; + + if (*wsaddrlen < sizeof(struct WS_sockaddr_un)) + return -1; + wun->sun_family = WS_AF_INET; + memcpy(&wun->sun_path, &un->sun_path, sizeof(wun->sun_path)); + *wsaddrlen = sizeof(struct WS_sockaddr_un); + return 0; + } case AF_UNSPEC: { memset(wsaddr,0,*wsaddrlen); return 0; diff --git a/include/Makefile.in b/include/Makefile.in index 49b174ed31..3513b88c23 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -11,6 +11,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 0000000000..4266e5f84b --- /dev/null +++ b/include/afunix.h @@ -0,0 +1,43 @@ +/* AFUNIX.H + * + * Copyright (C) the Wine project + * + * 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 __WINE_AFUNIX_H +#define __WINE_AFUNIX_H + +#define __WINE_UNIX_PATH_MAX 108 + +#ifdef USE_WS_PREFIX + +struct WS_sockaddr_un +{ + ADDRESS_FAMILY sun_family; + char sun_path[__WINE_UNIX_PATH_MAX]; +}; + +#else + +struct sockaddr_un +{ + ADDRESS_FAMILY sun_family; + char sun_path[__WINE_UNIX_PATH_MAX]; +}; + +#endif + +#endif /* __WINE_AFUNIX_H */
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=77930
Your paranoid android.
=== debiant (32 bit WoW report) ===
ws2_32: sock.c:3061: Test succeeded inside todo block: Test[1]: expected 0, got 0
Hello Richard, thanks for the patch!
It may help to include some tests for this functionality, both to confirm its correctness and to prevent future regressions.
On 9/2/20 6:58 AM, Richard W.M. Jones wrote:
This is the most minimal support for AF_UNIX. Windows 10 has had AF_UNIX support for a while: https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/
Signed-off-by: Richard W.M. Jones rjones@redhat.com
dlls/ws2_32/socket.c | 34 ++++++++++++++++++++++++++++++++++ include/Makefile.in | 1 + include/afunix.h | 43 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 4d2afa946b..b6378133db 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -132,6 +132,8 @@ # include <sys/time.h> #endif
+#include <sys/un.h>
#define NONAMELESSUNION #define NONAMELESSSTRUCT #include "ntstatus.h" @@ -151,6 +153,7 @@ #include "wshisotp.h" #include "mstcpip.h" #include "af_irda.h" +#include "afunix.h" #include "winnt.h" #define USE_WC_PREFIX /* For CMSG_DATA */ #include "iphlpapi.h" @@ -745,6 +748,7 @@ static const int ws_ipv6_map[][2] = static const int ws_af_map[][2] = { MAP_OPTION( AF_UNSPEC ),
- MAP_OPTION( AF_UNIX ), MAP_OPTION( AF_INET ), MAP_OPTION( AF_INET6 ),
#ifdef HAS_IPX @@ -1802,6 +1806,7 @@ static inline BOOL supported_pf(int pf) { switch (pf) {
- case WS_AF_UNIX: case WS_AF_INET: case WS_AF_INET6: return TRUE;
@@ -1900,6 +1905,18 @@ static unsigned int ws_sockaddr_ws2u(const struct WS_sockaddr* wsaddr, int wsadd memcpy(&uin->sin_addr,&win->sin_addr,4); /* 4 bytes = 32 address bits */ break; }
- case WS_AF_UNIX: {
struct sockaddr_un* un = (struct sockaddr_un *)uaddr;
const struct WS_sockaddr_un* wun = (const struct WS_sockaddr_un*)wsaddr;
if (wsaddrlen<sizeof(struct WS_sockaddr_un))
return 0;
uaddrlen = sizeof(struct sockaddr_un);
memset( uaddr, 0, uaddrlen );
un->sun_family = AF_UNIX;
memcpy(&un->sun_path, &wun->sun_path, sizeof(un->sun_path));
break;
- }
#ifdef HAS_IRDA case WS_AF_IRDA: { struct sockaddr_irda *uin = (struct sockaddr_irda *)uaddr; @@ -1984,6 +2001,12 @@ static BOOL is_sockaddr_bound(const struct sockaddr *uaddr, int uaddrlen) const struct sockaddr_in *in = (const struct sockaddr_in*) uaddr; return in->sin_port || memcmp(&in->sin_addr, &emptyAddr.sin_addr, sizeof(struct in_addr)); }
case AF_UNIX:
{
static const struct sockaddr_un emptyAddr;
const struct sockaddr_un *un = (const struct sockaddr_un*) uaddr;
return memcmp(&un->sun_path, &emptyAddr.sun_path, sizeof(un->sun_path));
} case AF_UNSPEC: return FALSE; default:
@@ -2108,6 +2131,17 @@ static int ws_sockaddr_u2ws(const struct sockaddr* uaddr, struct WS_sockaddr* ws *wsaddrlen = sizeof(struct WS_sockaddr_in); return 0; }
- case AF_UNIX: {
const struct sockaddr_un* un = (const struct sockaddr_un*)uaddr;
struct WS_sockaddr_un* wun = (struct WS_sockaddr_un*)wsaddr;
if (*wsaddrlen < sizeof(struct WS_sockaddr_un))
return -1;
wun->sun_family = WS_AF_INET;
memcpy(&wun->sun_path, &un->sun_path, sizeof(wun->sun_path));
*wsaddrlen = sizeof(struct WS_sockaddr_un);
return 0;
- } case AF_UNSPEC: { memset(wsaddr,0,*wsaddrlen); return 0;
diff --git a/include/Makefile.in b/include/Makefile.in index 49b174ed31..3513b88c23 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -11,6 +11,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 0000000000..4266e5f84b --- /dev/null +++ b/include/afunix.h @@ -0,0 +1,43 @@ +/* AFUNIX.H
- Copyright (C) the Wine project
- 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 __WINE_AFUNIX_H +#define __WINE_AFUNIX_H
+#define __WINE_UNIX_PATH_MAX 108
+#ifdef USE_WS_PREFIX
+struct WS_sockaddr_un +{
- ADDRESS_FAMILY sun_family;
- char sun_path[__WINE_UNIX_PATH_MAX];
+};
+#else
+struct sockaddr_un +{
- ADDRESS_FAMILY sun_family;
- char sun_path[__WINE_UNIX_PATH_MAX];
+};
+#endif
+#endif /* __WINE_AFUNIX_H */