The detailed instructions are at the bottom of the README if you search for "WINDOWS": https://gitlab.com/nbdkit/nbdkit/-/blob/master/README These basic commands should work: $ mingw64-configure --disable-ocaml --disable-perl --disable-vddk $ mingw64-make and the binary should be runnable if Wine is installed, eg: $ ./nbdkit.exe --dump-config ... host_cpu=x86_64 host_os=mingw32 ... Getting the tests to work under Wine is ... well, a tad more tedious. There are several issues: - Windows now supports AF_UNIX, but Wine does not. - Most tests use Unix domain sockets (ie. nbdkit -U) because using possibly public TCP ports during tests is not cool and also difficult to deconflict. So AF_UNIX support is really needed to run nbdkit tests in any detail. - I patched Wine to add AF_UNIX support (see attached). However since then Wine code has changed quite significantly in the way it creates sockets so my patch doesn't even remotely work and I can't see an easy way to fix it. Therefore you must apply the attached patch on top of 7ec069d85f5235db ("ntdll/tests: Fix virtual test failures on win10pro.") Only 5592 commits behind head! - ./configure --enable-win64 && make - For some reason I had to hand-edit dlls/gdi32/Makefile to remove the tools/wrc/wrc -pthread parameter. I'm pretty sure I didn't need to do that before. There could be an upstream commit we are missing. If you do all of that and build Wine then you should be able to set $PATH to point to the patched Wine build directory and run the tests as so: $ PATH=~/d/wine:$PATH mingw64-make check -C tests Tests in !tests directory fail for miscellaneous reasons. Most tests will be skipped but for me at least a significant number pass. I get: ===========================================================================Testsuite summary for nbdkit 1.25.7 ===========================================================================# TOTAL: 203 # PASS: 75 # SKIP: 128 # XFAIL: 0 # FAIL: 0 # XPASS: 0 # ERROR: 0 =========================================================================== I would recommend adding ?WINEDEBUG=warn+all? if nothing seems to be working. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-top is 'top' for virtual machines. Tiny program with many powerful monitoring features, net stats, disk stats, logging, etc. http://people.redhat.com/~rjones/virt-top -------------- next part -------------->From 3dbccc9012f2f19516809f3e116f0e5c99ba9eb5 Mon Sep 17 00:00:00 2001From: "Richard W.M. Jones" <rjones at redhat.com> Date: Thu, 27 Aug 2020 21:44:57 +0100 Subject: [PATCH] ws2_32: Very minimal support for AF_UNIX. 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 at redhat.com> --- dlls/ws2_32/socket.c | 56 ++++++++++++++++++++++++++++++++++++++++++++ include/Makefile.in | 1 + include/afunix.h | 43 ++++++++++++++++++++++++++++++++++ 3 files changed, 100 insertions(+) create mode 100644 include/afunix.h diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index b7a570043cd..269e0063479 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,36 @@ 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; + int num; + LPWSTR win_path; + char *unix_path; + + if (wsaddrlen<sizeof(struct WS_sockaddr_un)) + return 0; + uaddrlen = sizeof(struct sockaddr_un); + memset( uaddr, 0, uaddrlen ); + un->sun_family = AF_UNIX; + /* Note that in Win32 sun_path is "a null-terminated UTF-8 + * file system path". We have to translate to a Unix path. + */ + num = MultiByteToWideChar(CP_UTF8, 0, wun->sun_path, -1, NULL, 0); + win_path = HeapAlloc(GetProcessHeap(), 0, num * sizeof(WCHAR)); + if (win_path == NULL) + return 0; + MultiByteToWideChar(CP_UTF8, 0, wun->sun_path, -1, win_path, num); + unix_path = wine_get_unix_file_name(win_path); + heap_free(win_path); + if (!unix_path || strlen(unix_path) > sizeof(un->sun_path)) { + heap_free(unix_path); + return 0; + } + memcpy(&un->sun_path, unix_path, strlen(unix_path)); + heap_free(unix_path); + break; + } #ifdef HAS_IRDA case WS_AF_IRDA: { struct sockaddr_irda *uin = (struct sockaddr_irda *)uaddr; @@ -1984,6 +2019,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 +2149,21 @@ 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; + /* XXX We might want to translate the Unix path to an NT path + * here, or maybe not depending on whether we expect the + * caller would need to open this path or simply display it. + */ + 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 49b174ed319..3513b88c237 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 00000000000..4266e5f84b1 --- /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 */ -- 2.31.1
On Tue, May 18, 2021 at 02:40:07PM +0100, Richard W.M. Jones wrote:> - I patched Wine to add AF_UNIX support (see attached). However > since then Wine code has changed quite significantly in the way it > creates sockets so my patch doesn't even remotely work and I can't > see an easy way to fix it. Therefore you must apply the attached > patch on top of 7ec069d85f5235db ("ntdll/tests: Fix virtual test > failures on win10pro.") Only 5592 commits behind head!Update! After taking another look at the code, I fixed this so you can now use Wine from the master branch. I posted the latest patch upstream here, and it's also attached to this message. https://www.winehq.org/pipermail/wine-devel/2021-May/187049.html> - For some reason I had to hand-edit dlls/gdi32/Makefile to remove > the tools/wrc/wrc -pthread parameter. I'm pretty sure I didn't > need to do that before. There could be an upstream commit we are > missing.This is no longer necessary. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-top is 'top' for virtual machines. Tiny program with many powerful monitoring features, net stats, disk stats, logging, etc. http://people.redhat.com/~rjones/virt-top -------------- next part -------------->From ed8f0bf0337ac90e9f19f5c94ec5be779d9ee433 Mon Sep 17 00:00:00 2001From: "Richard W.M. Jones" <rjones at redhat.com> Date: Thu, 27 Aug 2020 21:44:57 +0100 Subject: [PATCH] ws2_32: Very minimal support for AF_UNIX. 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 at redhat.com> --- dlls/ws2_32/protocol.c | 1 + dlls/ws2_32/socket.c | 52 ++++++++++++++++++++++++++++++++++++ dlls/ws2_32/ws2_32_private.h | 3 +++ include/Makefile.in | 1 + include/afunix.h | 43 +++++++++++++++++++++++++++++ server/sock.c | 1 + 6 files changed, 101 insertions(+) create mode 100644 include/afunix.h diff --git a/dlls/ws2_32/protocol.c b/dlls/ws2_32/protocol.c index 15616fdaf34..b6e98ad70fb 100644 --- a/dlls/ws2_32/protocol.c +++ b/dlls/ws2_32/protocol.c @@ -71,6 +71,7 @@ static const int ws_eai_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 diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 2ba1982b1d9..1851abccef9 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -1599,6 +1599,7 @@ static inline BOOL supported_pf(int pf) { switch (pf) { + case WS_AF_UNIX: case WS_AF_INET: case WS_AF_INET6: return TRUE; @@ -1688,6 +1689,36 @@ unsigned int ws_sockaddr_ws2u( const struct WS_sockaddr *wsaddr, int wsaddrlen, 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; + int num; + LPWSTR win_path; + char *unix_path; + + if (wsaddrlen<sizeof(struct WS_sockaddr_un)) + return 0; + uaddrlen = sizeof(struct sockaddr_un); + memset( uaddr, 0, uaddrlen ); + un->sun_family = AF_UNIX; + /* Note that in Win32 sun_path is "a null-terminated UTF-8 + * file system path". We have to translate to a Unix path. + */ + num = MultiByteToWideChar(CP_UTF8, 0, wun->sun_path, -1, NULL, 0); + win_path = HeapAlloc(GetProcessHeap(), 0, num * sizeof(WCHAR)); + if (win_path == NULL) + return 0; + MultiByteToWideChar(CP_UTF8, 0, wun->sun_path, -1, win_path, num); + unix_path = wine_get_unix_file_name(win_path); + heap_free(win_path); + if (!unix_path || strlen(unix_path) > sizeof(un->sun_path)) { + heap_free(unix_path); + return 0; + } + memcpy(&un->sun_path, unix_path, strlen(unix_path)); + heap_free(unix_path); + break; + } #ifdef HAS_IRDA case WS_AF_IRDA: { struct sockaddr_irda *uin = (struct sockaddr_irda *)uaddr; @@ -1772,6 +1803,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: @@ -1896,6 +1933,21 @@ int ws_sockaddr_u2ws(const struct sockaddr *uaddr, struct WS_sockaddr *wsaddr, i *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; + /* XXX We might want to translate the Unix path to an NT path + * here, or maybe not depending on whether we expect the + * caller would need to open this path or simply display it. + */ + 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/dlls/ws2_32/ws2_32_private.h b/dlls/ws2_32/ws2_32_private.h index e86a3569510..465299d0159 100644 --- a/dlls/ws2_32/ws2_32_private.h +++ b/dlls/ws2_32/ws2_32_private.h @@ -122,6 +122,8 @@ # include <sys/time.h> #endif +#include <sys/un.h> + #define NONAMELESSUNION #define NONAMELESSSTRUCT #include "ntstatus.h" @@ -141,6 +143,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" diff --git a/include/Makefile.in b/include/Makefile.in index 9822bce6bdd..119f8fc5266 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 00000000000..4266e5f84b1 --- /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 */ diff --git a/server/sock.c b/server/sock.c index 565fb4c5a2c..b9de0eb8815 100644 --- a/server/sock.c +++ b/server/sock.c @@ -932,6 +932,7 @@ static int get_unix_family( int family ) { switch (family) { + case WS_AF_UNIX: return AF_UNIX; case WS_AF_INET: return AF_INET; case WS_AF_INET6: return AF_INET6; #ifdef HAS_IPX -- 2.31.1