[PATCH nbdkit 0/13] Port to Windows without using a separate library.
Also available here: https://github.com/rwmjones/nbdkit/tree/2020-windows-mingw-nolib After a lot of work I have made the port to Windows work without using a separate library. Instead, on Windows only, we build an "import library" (library of stubs) which resolves references to nbdkit_* functions in the main program and fixes up the plugin, basically the first technique outlined in this email: https://www.redhat.com/archives/libguestfs/2020-August/msg00268.html Most tests fail, unsurprisingly. The vast majority fail because we lack support for Unix domain sockets. There is some hope that we could add this: https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/ Although this could fix many tests, it's probably not going to be very useful for actual Windows users. Another large cause of test failures is lack of --run option which might also be fixed with a lot of effort. As before it's entirely possible to develop on, compile and test this series using only the tools provided in Fedora or RHEL. You need a few mingw64-* packages and wine. (Note you don't need to run wine explicitly, there should be a binfmt handler installed which allows you to run nbdkit.exe directly). Apart from having to use ./nbdkit.exe to run the wrapper, it should all work the same way, eg: ./nbdkit.exe -f -v memory 1G ./nbdkit.exe -f -v file disk.img starts a RAM disk or exports a file. This patch series should contain fixes for everything picked up on in previous reviews. Rich.
Especially on Windows, some common functions are missing. Use the autoconf LIBOBJS mechanism to replace these functions. This includes replacement functions for: Function names Implementation Origin getdelim, getline general purpose NetBSD under a compatible license openlog, syslog, Win32 written by me vsyslog realpath Win32 written by me strndup general purpose NetBSD under a compatible license This should do nothing on existing supported platforms. It is only intended in preparation for porting nbdkit to Windows. --- configure.ac | 22 +++++++ Makefile.am | 1 + common/replacements/Makefile.am | 52 +++++++++++++++ common/replacements/win32/Makefile.am | 45 +++++++++++++ server/Makefile.am | 3 + common/replacements/getline.h | 48 ++++++++++++++ common/replacements/realpath.h | 47 ++++++++++++++ common/replacements/strndup.h | 47 ++++++++++++++ common/replacements/syslog.h | 66 +++++++++++++++++++ server/crypto.c | 2 +- server/log-syslog.c | 2 +- server/main.c | 9 +-- server/public.c | 2 + common/replacements/getdelim.c | 84 +++++++++++++++++++++++++ common/replacements/getline.c | 46 ++++++++++++++ common/replacements/openlog.c | 61 ++++++++++++++++++ common/replacements/realpath.c | 80 +++++++++++++++++++++++ common/replacements/strndup.c | 58 +++++++++++++++++ common/replacements/syslog.c | 61 ++++++++++++++++++ common/replacements/vsyslog.c | 73 +++++++++++++++++++++ common/replacements/win32/nbdkit-cat.mc | 37 +++++++++++ .gitignore | 4 ++ 22 files changed, 844 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index 35384429..41e15b40 100644 --- a/configure.ac +++ b/configure.ac @@ -337,6 +337,17 @@ AC_CHECK_FUNCS([\ ppoll \ posix_fadvise]) +dnl Replacement functions that we provide for some platforms. +AC_CONFIG_LIBOBJ_DIR([common/replacements]) +AC_REPLACE_FUNCS([\ + getdelim \ + getline \ + openlog \ + realpath \ + strndup \ + syslog \ + vsyslog]) + dnl Check whether printf("%m") works AC_CACHE_CHECK([whether the printf family supports %m], [nbdkit_cv_func_printf_percent_m], @@ -462,6 +473,15 @@ AS_CASE([$host_os], ) AC_MSG_RESULT([$is_windows]) AC_SUBST([NO_UNDEFINED_ON_WINDOWS]) +AM_CONDITIONAL([IS_WINDOWS],[test "x$is_windows" = "xyes"]) + +dnl For Windows, look for the mc/windmc utility. +dnl XXX Do we need to check for mc.exe as well? +AS_IF([test "x$is_windows" = "xyes"],[ + AC_CHECK_TOOLS([MC],[windmc mc],[no]) + AS_IF([test "x$MC" = "xno"], + [AC_MSG_ERROR([mc/windmc utility must be available when compiling for Windows])]) +]) AC_SEARCH_LIBS([getaddrinfo], [network socket]) @@ -1105,6 +1125,8 @@ AC_CONFIG_FILES([Makefile common/include/Makefile common/protocol/Makefile common/regions/Makefile + common/replacements/Makefile + common/replacements/win32/Makefile common/utils/Makefile docs/Makefile include/Makefile diff --git a/Makefile.am b/Makefile.am index 0ca53d64..a9d6d164 100644 --- a/Makefile.am +++ b/Makefile.am @@ -74,6 +74,7 @@ SUBDIRS = \ include \ common/include \ common/protocol \ + common/replacements \ common/utils \ server \ $(NULL) diff --git a/common/replacements/Makefile.am b/common/replacements/Makefile.am new file mode 100644 index 00000000..e5a5612f --- /dev/null +++ b/common/replacements/Makefile.am @@ -0,0 +1,52 @@ +# nbdkit +# Copyright (C) 2019 Red Hat Inc. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the name of Red Hat nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. + +include $(top_srcdir)/common-rules.mk + +SUBDIRS = win32 + +noinst_LTLIBRARIES = libcompat.la +# sources should be empty +libcompat_la_SOURCES = +libcompat_la_LIBADD = $(LTLIBOBJS) + +EXTRA_DIST = \ + getdelim.c \ + getline.c \ + getline.h \ + openlog.c \ + realpath.c \ + realpath.h \ + strndup.c \ + strndup.h \ + syslog.c \ + syslog.h \ + vsyslog.c diff --git a/common/replacements/win32/Makefile.am b/common/replacements/win32/Makefile.am new file mode 100644 index 00000000..8b91709e --- /dev/null +++ b/common/replacements/win32/Makefile.am @@ -0,0 +1,45 @@ +# nbdkit +# Copyright (C) 2019 Red Hat Inc. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the name of Red Hat nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. + +include $(top_srcdir)/common-rules.mk + +EXTRA_DIST = nbdkit-cat.mc + +if IS_WINDOWS + +# Build the message catalog. +noinst_DATA = MSG00001.bin nbdkit-cat.h nbdkit-cat.rc + +$(noinst_DATA): nbdkit-cat.mc + rm -f $@ + $(MC) $< + +endif diff --git a/server/Makefile.am b/server/Makefile.am index 58b22341..d7150f52 100644 --- a/server/Makefile.am +++ b/server/Makefile.am @@ -84,6 +84,7 @@ nbdkit_CPPFLAGS = \ -I$(top_srcdir)/include \ -I$(top_srcdir)/common/include \ -I$(top_srcdir)/common/protocol \ + -I$(top_srcdir)/common/replacements \ -I$(top_srcdir)/common/utils \ $(NULL) nbdkit_CFLAGS = \ @@ -99,6 +100,7 @@ nbdkit_LDADD = \ $(DL_LIBS) \ $(top_builddir)/common/protocol/libprotocol.la \ $(top_builddir)/common/utils/libutils.la \ + $(top_builddir)/common/replacements/libcompat.la \ $(NULL) nbdkit_LDFLAGS = \ $(PTHREAD_LIBS) \ @@ -147,6 +149,7 @@ test_public_CPPFLAGS = \ -I$(top_srcdir)/include \ -I$(top_srcdir)/common/include \ -I$(top_srcdir)/common/protocol \ + -I$(top_srcdir)/common/replacements \ -I$(top_srcdir)/common/utils \ $(NULL) test_public_CFLAGS = $(WARNINGS_CFLAGS) $(VALGRIND_CFLAGS) diff --git a/common/replacements/getline.h b/common/replacements/getline.h new file mode 100644 index 00000000..6034d85d --- /dev/null +++ b/common/replacements/getline.h @@ -0,0 +1,48 @@ +/* nbdkit + * Copyright (C) 2019 Red Hat Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Red Hat nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef NBDKIT_GETLINE_H +#define NBDKIT_GETLINE_H + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> + +#ifndef HAVE_GETLINE + +ssize_t getline (char **lineptr, size_t *n, FILE *stream); +ssize_t getdelim (char **lineptr, size_t *n, int delim, FILE *stream); + +#endif + +#endif /* NBDKIT_GETLINE_H */ diff --git a/common/replacements/realpath.h b/common/replacements/realpath.h new file mode 100644 index 00000000..f9d32bb4 --- /dev/null +++ b/common/replacements/realpath.h @@ -0,0 +1,47 @@ +/* nbdkit + * Copyright (C) 2019 Red Hat Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Red Hat nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef NBDKIT_REALPATH_H +#define NBDKIT_REALPATH_H + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> + +#ifndef HAVE_REALPATH + +char *realpath (const char *path, char *out); + +#endif + +#endif /* NBDKIT_REALPATH_H */ diff --git a/common/replacements/strndup.h b/common/replacements/strndup.h new file mode 100644 index 00000000..e8a6d4a6 --- /dev/null +++ b/common/replacements/strndup.h @@ -0,0 +1,47 @@ +/* nbdkit + * Copyright (C) 2019 Red Hat Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Red Hat nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef NBDKIT_STRNDUP_H +#define NBDKIT_STRNDUP_H + +#include <config.h> + +#include <stddef.h> +#include <string.h> + +#ifndef HAVE_STRNDUP + +char *strndup(const char *s, size_t n); + +#endif + +#endif /* NBDKIT_STRNDUP_H */ diff --git a/common/replacements/syslog.h b/common/replacements/syslog.h new file mode 100644 index 00000000..6918a4a3 --- /dev/null +++ b/common/replacements/syslog.h @@ -0,0 +1,66 @@ +/* nbdkit + * Copyright (C) 2019 Red Hat Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Red Hat nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* Replacement for syslog for platforms which lack it. Note this only + * implements "just enough syslog" for nbdkit. It's not a general + * replacement. + */ + +#ifndef NBDKIT_SYSLOG_H +#define NBDKIT_SYSLOG_H + +#include <config.h> + +#ifdef HAVE_SYSLOG_H + +#include_next <syslog.h> + +#else + +#include <stdarg.h> + +/* Since the replacement function ignores the priority field, we only + * need to define these to any integer. + */ +#define LOG_PID 0 +#define LOG_ERR 0 +#define LOG_DAEMON 0 + +extern void openlog (const char *ident, int option, int facility); +extern void syslog (int pri, const char *fmt, ...) + __attribute__ ((format (printf, 2, 3))); +extern void vsyslog (int pri, const char *fmt, va_list args) + __attribute__ ((format (printf, 2, 0))); + +#endif /* !HAVE_SYSLOG_H */ + +#endif /* NBDKIT_SYSLOG_H */ diff --git a/server/crypto.c b/server/crypto.c index d291f4e7..0d3d4e8c 100644 --- a/server/crypto.c +++ b/server/crypto.c @@ -41,12 +41,12 @@ #include <string.h> #include <unistd.h> #include <fcntl.h> -#include <limits.h> #include <errno.h> #include <sys/types.h> #include <assert.h> #include "internal.h" +#include "realpath.h" #ifdef HAVE_GNUTLS diff --git a/server/log-syslog.c b/server/log-syslog.c index fdac45f1..6e9a1bfd 100644 --- a/server/log-syslog.c +++ b/server/log-syslog.c @@ -37,9 +37,9 @@ #include <stdarg.h> #include <string.h> #include <errno.h> -#include <syslog.h> #include "internal.h" +#include "syslog.h" /* Tempted to use LOG_FTP instead of LOG_DAEMON! */ static const int PRIORITY = LOG_DAEMON|LOG_ERR; diff --git a/server/main.c b/server/main.c index 17c4c324..78da5ee8 100644 --- a/server/main.c +++ b/server/main.c @@ -42,7 +42,6 @@ #include <limits.h> #include <errno.h> #include <assert.h> -#include <syslog.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/socket.h> @@ -60,11 +59,13 @@ #include <dlfcn.h> #include "ascii-string.h" - -#include "internal.h" +#include "exit-with-parent.h" #include "nbd-protocol.h" +#include "strndup.h" +#include "syslog.h" + +#include "internal.h" #include "options.h" -#include "exit-with-parent.h" #ifdef ENABLE_LIBFUZZER #define main fuzzer_main diff --git a/server/public.c b/server/public.c index d10d466e..1f7e1af0 100644 --- a/server/public.c +++ b/server/public.c @@ -54,6 +54,8 @@ #include "ascii-ctype.h" #include "ascii-string.h" #include "get-current-dir-name.h" +#include "getline.h" +#include "realpath.h" #include "internal.h" diff --git a/common/replacements/getdelim.c b/common/replacements/getdelim.c new file mode 100644 index 00000000..97421cb5 --- /dev/null +++ b/common/replacements/getdelim.c @@ -0,0 +1,84 @@ +/* $NetBSD: getdelim.c,v 1.2 2015/12/25 20:12:46 joerg Exp $ */ +/* NetBSD-src: getline.c,v 1.2 2014/09/16 17:23:50 christos Exp */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> + +#ifndef HAVE_GETDELIM + +#include "getline.h" + +ssize_t +getdelim (char **buf, size_t *bufsiz, int delimiter, FILE *fp) +{ + char *ptr, *eptr; + + if (*buf == NULL || *bufsiz == 0) { + *bufsiz = BUFSIZ; + if ((*buf = malloc (*bufsiz)) == NULL) + return -1; + } + + for (ptr = *buf, eptr = *buf + *bufsiz;;) { + int c = fgetc (fp); + if (c == -1) { + if (feof (fp)) { + ssize_t diff = (ssize_t)(ptr - *buf); + if (diff != 0) { + *ptr = '\0'; + return diff; + } + } + return -1; + } + *ptr++ = c; + if (c == delimiter) { + *ptr = '\0'; + return ptr - *buf; + } + if (ptr + 2 >= eptr) { + char *nbuf; + size_t nbufsiz = *bufsiz * 2; + ssize_t d = ptr - *buf; + if ((nbuf = realloc (*buf, nbufsiz)) == NULL) + return -1; + *buf = nbuf; + *bufsiz = nbufsiz; + eptr = nbuf + nbufsiz; + ptr = nbuf + d; + } + } +} + +#endif diff --git a/common/replacements/getline.c b/common/replacements/getline.c new file mode 100644 index 00000000..e9caf496 --- /dev/null +++ b/common/replacements/getline.c @@ -0,0 +1,46 @@ +/* $NetBSD: getline.c,v 1.2 2015/12/25 20:12:46 joerg Exp $ */ +/* NetBSD-src: getline.c,v 1.2 2014/09/16 17:23:50 christos Exp */ + +/*- + * Copyright (c) 2011 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <config.h> +#include <stdio.h> + +#ifndef HAVE_GETLINE + +#include "getline.h" + +ssize_t +getline (char **buf, size_t *bufsiz, FILE *fp) +{ + return getdelim (buf, bufsiz, '\n', fp); +} + +#endif diff --git a/common/replacements/openlog.c b/common/replacements/openlog.c new file mode 100644 index 00000000..1081d319 --- /dev/null +++ b/common/replacements/openlog.c @@ -0,0 +1,61 @@ +/* nbdkit + * Copyright (C) 2019 Red Hat Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Red Hat nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> + +#ifndef HAVE_OPENLOG_H + +#include "syslog.h" + +#ifdef WIN32 + +/* Replacement openlog for Win32. */ + +#include <windows.h> + +HANDLE event_source = INVALID_HANDLE_VALUE; + +void +openlog (const char *ident, int option, int facility) +{ + event_source = RegisterEventSource (NULL, ident); +} + +#else /* !WIN32 */ +#error "no replacement openlog is available on this platform" +#endif + +#endif /* !HAVE_SYSLOG_H */ diff --git a/common/replacements/realpath.c b/common/replacements/realpath.c new file mode 100644 index 00000000..4562e8c3 --- /dev/null +++ b/common/replacements/realpath.c @@ -0,0 +1,80 @@ +/* nbdkit + * Copyright (C) 2019 Red Hat Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Red Hat nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* Replacement for realpath for platforms which lack this function. */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> + +#ifndef HAVE_REALPATH + +#include "realpath.h" + +#ifdef WIN32 + +/* Replacement realpath for Win32. + * + * Note this is not thread-safe, but should be fine for all the + * uses in the server and ordinary plugins. + */ + +#include <windows.h> + +char * +realpath (const char *path, char *out) +{ + TCHAR buf[MAX_PATH]; + int r; + + r = GetFullPathNameA (path, MAX_PATH, buf, NULL); + if (r == 0) { + errno = GetLastError (); + return NULL; + } + + out = malloc (r + 1); + if (out == NULL) + return NULL; + memcpy (out, buf, r); + out[r] = '\0'; + + return out; +} + +#else /* !WIN32 */ +#error "no replacement realpath is available on this platform" +#endif + +#endif /* !HAVE_REALPATH */ diff --git a/common/replacements/strndup.c b/common/replacements/strndup.c new file mode 100644 index 00000000..976a25f4 --- /dev/null +++ b/common/replacements/strndup.c @@ -0,0 +1,58 @@ +/* $NetBSD: strndup.c,v 1.4 2007/07/03 12:11:09 nakayama Exp $ */ + +/* + * Copyright (c) 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* $NetBSD: strndup.c,v 1.4 2007/07/03 12:11:09 nakayama Exp $ */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#ifndef HAVE_STRNDUP + +char * +strndup (const char *str, size_t n) +{ + size_t len; + char *copy; + + for (len = 0; len < n && str[len]; len++) + continue; + + if (!(copy = malloc(len + 1))) + return NULL; + memcpy (copy, str, len); + copy[len] = '\0'; + return copy; +} + +#endif /* !HAVE_STRNDUP */ diff --git a/common/replacements/syslog.c b/common/replacements/syslog.c new file mode 100644 index 00000000..89ef73a7 --- /dev/null +++ b/common/replacements/syslog.c @@ -0,0 +1,61 @@ +/* nbdkit + * Copyright (C) 2019 Red Hat Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Red Hat nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> + +#ifndef HAVE_SYSLOG_H + +#include "syslog.h" + +#ifdef WIN32 + +/* Replacement syslog for Win32. */ + +void +syslog (int pri, const char *fmt, ...) +{ + va_list args; + + va_start (args, fmt); + vsyslog (pri, fmt, args); + va_end (args); +} + +#else /* !WIN32 */ +#error "no replacement syslog is available on this platform" +#endif + +#endif /* !HAVE_SYSLOG_H */ diff --git a/common/replacements/vsyslog.c b/common/replacements/vsyslog.c new file mode 100644 index 00000000..d1ab267e --- /dev/null +++ b/common/replacements/vsyslog.c @@ -0,0 +1,73 @@ +/* nbdkit + * Copyright (C) 2019 Red Hat Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Red Hat nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> + +#ifndef HAVE_SYSLOG_H + +#include "syslog.h" + +#ifdef WIN32 + +/* Replacement vsyslog for Win32. */ + +#include <windows.h> + +#include "win32/nbdkit-cat.h" + +extern HANDLE event_source; + +void +vsyslog (int pri, const char *fmt, va_list args) +{ + char *str; + const char *strs[1]; + + if (vasprintf (&str, fmt, args) == -1) + return; + strs[0] = str; + + ReportEventA (event_source, EVENTLOG_ERROR_TYPE, 0, + NBDKIT_SYSLOG_ERROR, NULL, 1, 0, strs, NULL); + + free (str); +} + +#else /* !WIN32 */ +#error "no replacement vsyslog is available on this platform" +#endif + +#endif /* !HAVE_SYSLOG_H */ diff --git a/common/replacements/win32/nbdkit-cat.mc b/common/replacements/win32/nbdkit-cat.mc new file mode 100644 index 00000000..dc43ad01 --- /dev/null +++ b/common/replacements/win32/nbdkit-cat.mc @@ -0,0 +1,37 @@ +;// nbdkit +;// Copyright (C) 2019-2020 Red Hat Inc. +;// +;// Redistribution and use in source and binary forms, with or without +;// modification, are permitted provided that the following conditions are +;// met: +;// +;// * Redistributions of source code must retain the above copyright +;// notice, this list of conditions and the following disclaimer. +;// +;// * Redistributions in binary form must reproduce the above copyright +;// notice, this list of conditions and the following disclaimer in the +;// documentation and/or other materials provided with the distribution. +;// +;// * Neither the name of Red Hat nor the names of its contributors may be +;// used to endorse or promote products derived from this software without +;// specific prior written permission. +;// +;// THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND +;// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +;// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +;// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR +;// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +;// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +;// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +;// USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +;// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +;// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +;// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +;// SUCH DAMAGE. + +MessageId=1 +Severity=Error +SymbolicName=NBDKIT_SYSLOG_ERROR +Language=English +%1 +. diff --git a/.gitignore b/.gitignore index 2c463909..ca36d9c2 100644 --- a/.gitignore +++ b/.gitignore @@ -46,6 +46,10 @@ plugins/*/*.3 /common/include/test-tvdiff /common/protocol/generate-protostrings.sh /common/protocol/protostrings.c +/common/replacements/libcompat.a +/common/replacements/win32/MSG00001.bin +/common/replacements/win32/nbdkit-cat.h +/common/replacements/win32/nbdkit-cat.rc /common/utils/test-quotes /common/utils/test-vector /compile -- 2.27.0
On 8/20/20 6:37 AM, Richard W.M. Jones wrote:
Especially on Windows, some common functions are missing. Use the autoconf LIBOBJS mechanism to replace these functions.
This includes replacement functions for:
Function names Implementation Origin
getdelim, getline general purpose NetBSD under a compatible license
openlog, syslog, Win32 written by me vsyslog
realpath Win32 written by me
strndup general purpose NetBSD under a compatible license
This should do nothing on existing supported platforms. It is only intended in preparation for porting nbdkit to Windows. ---
+++ b/common/replacements/Makefile.am @@ -0,0 +1,52 @@ +# nbdkit +# Copyright (C) 2019 Red Hat Inc.
2020 if you want; but that's a lot of files to edit in the series. -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3226 Virtualization: qemu.org | libvirt.org
On Thu, Aug 20, 2020 at 10:26:06AM -0500, Eric Blake wrote:
On 8/20/20 6:37 AM, Richard W.M. Jones wrote:
Especially on Windows, some common functions are missing. Use the autoconf LIBOBJS mechanism to replace these functions.
This includes replacement functions for:
Function names Implementation Origin
getdelim, getline general purpose NetBSD under a compatible license
openlog, syslog, Win32 written by me vsyslog
realpath Win32 written by me
strndup general purpose NetBSD under a compatible license
This should do nothing on existing supported platforms. It is only intended in preparation for porting nbdkit to Windows. ---
+++ b/common/replacements/Makefile.am @@ -0,0 +1,52 @@ +# nbdkit +# Copyright (C) 2019 Red Hat Inc.
2020 if you want; but that's a lot of files to edit in the series.
They're left over from when I wrote this particular commit in 2018/2019. I may change them if I have time. Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com Fedora Windows cross-compiler. Compile Windows programs, test, and build Windows installers. Over 100 libraries supported. http://fedoraproject.org/wiki/MinGW
--- plugins/data/Makefile.am | 2 ++ plugins/data/format.c | 1 + 2 files changed, 3 insertions(+) diff --git a/plugins/data/Makefile.am b/plugins/data/Makefile.am index de6e80bb..01e5eec6 100644 --- a/plugins/data/Makefile.am +++ b/plugins/data/Makefile.am @@ -49,6 +49,7 @@ nbdkit_data_plugin_la_CPPFLAGS = \ -I$(top_srcdir)/include \ -I$(top_srcdir)/common/include \ -I$(top_srcdir)/common/allocators \ + -I$(top_srcdir)/common/replacements \ -I$(top_srcdir)/common/utils \ $(NULL) nbdkit_data_plugin_la_CFLAGS = \ @@ -62,6 +63,7 @@ nbdkit_data_plugin_la_LDFLAGS = \ nbdkit_data_plugin_la_LIBADD = \ $(top_builddir)/common/allocators/liballocators.la \ $(top_builddir)/common/utils/libutils.la \ + $(top_builddir)/common/replacements/libcompat.la \ $(GNUTLS_LIBS) \ $(NULL) diff --git a/plugins/data/format.c b/plugins/data/format.c index 89f69357..9cb1a884 100644 --- a/plugins/data/format.c +++ b/plugins/data/format.c @@ -46,6 +46,7 @@ #include "ispowerof2.h" #include "rounding.h" #include "allocator.h" +#include "strndup.h" #include "format.h" /* Store file at current offset in the allocator, updating the offset. */ -- 2.27.0
On Windows strndup is missing. --- plugins/memory/Makefile.am | 2 ++ 1 file changed, 2 insertions(+) diff --git a/plugins/memory/Makefile.am b/plugins/memory/Makefile.am index a88c45c9..5915baf4 100644 --- a/plugins/memory/Makefile.am +++ b/plugins/memory/Makefile.am @@ -43,6 +43,7 @@ nbdkit_memory_plugin_la_SOURCES = \ nbdkit_memory_plugin_la_CPPFLAGS = \ -I$(top_srcdir)/include \ -I$(top_srcdir)/common/allocators \ + -I$(top_srcdir)/common/replacements \ -I$(top_srcdir)/common/utils \ $(NULL) nbdkit_memory_plugin_la_CFLAGS = $(WARNINGS_CFLAGS) @@ -52,6 +53,7 @@ nbdkit_memory_plugin_la_LDFLAGS = \ $(NULL) nbdkit_memory_plugin_la_LIBADD = \ $(top_builddir)/common/allocators/liballocators.la \ + $(top_builddir)/common/replacements/libcompat.la \ $(top_builddir)/common/utils/libutils.la \ $(NULL) -- 2.27.0
This is really a replacement for a missing platform function, so use the same LIBOBJS mechanism to replace it. --- configure.ac | 2 +- common/include/Makefile.am | 6 --- common/replacements/Makefile.am | 14 ++++++ plugins/floppy/Makefile.am | 1 + common/replacements/get_current_dir_name.h | 48 +++++++++++++++++++ server/public.c | 2 +- .../get_current_dir_name.c} | 10 ++-- .../test-current-dir-name.c | 2 +- plugins/floppy/virtual-floppy.c | 2 +- .gitignore | 2 +- 10 files changed, 72 insertions(+), 17 deletions(-) diff --git a/configure.ac b/configure.ac index 41e15b40..0066fc45 100644 --- a/configure.ac +++ b/configure.ac @@ -327,7 +327,6 @@ AC_CHECK_FUNCS([\ fdatasync \ flockfile \ funlockfile \ - get_current_dir_name \ mkostemp \ mlock \ mlockall \ @@ -340,6 +339,7 @@ AC_CHECK_FUNCS([\ dnl Replacement functions that we provide for some platforms. AC_CONFIG_LIBOBJ_DIR([common/replacements]) AC_REPLACE_FUNCS([\ + get_current_dir_name \ getdelim \ getline \ openlog \ diff --git a/common/include/Makefile.am b/common/include/Makefile.am index 151c2ae4..a7d0d026 100644 --- a/common/include/Makefile.am +++ b/common/include/Makefile.am @@ -38,7 +38,6 @@ EXTRA_DIST = \ ascii-string.h \ byte-swapping.h \ exit-with-parent.h \ - get-current-dir-name.h \ isaligned.h \ ispowerof2.h \ iszero.h \ @@ -56,7 +55,6 @@ TESTS = \ test-ascii-ctype \ test-ascii-string \ test-byte-swapping \ - test-current-dir-name \ test-isaligned \ test-ispowerof2 \ test-iszero \ @@ -79,10 +77,6 @@ test_byte_swapping_SOURCES = test-byte-swapping.c byte-swapping.h test_byte_swapping_CPPFLAGS = -I$(srcdir) test_byte_swapping_CFLAGS = $(WARNINGS_CFLAGS) -test_current_dir_name_SOURCES = test-current-dir-name.c get-current-dir-name.h -test_current_dir_name_CPPFLAGS = -I$(srcdir) -test_current_dir_name_CFLAGS = $(WARNINGS_CFLAGS) - test_isaligned_SOURCES = test-isaligned.c isaligned.h test_isaligned_CPPFLAGS = -I$(srcdir) test_isaligned_CFLAGS = $(WARNINGS_CFLAGS) diff --git a/common/replacements/Makefile.am b/common/replacements/Makefile.am index e5a5612f..9494189b 100644 --- a/common/replacements/Makefile.am +++ b/common/replacements/Makefile.am @@ -39,6 +39,8 @@ libcompat_la_SOURCES = libcompat_la_LIBADD = $(LTLIBOBJS) EXTRA_DIST = \ + get_current_dir_name.c \ + get_current_dir_name.h \ getdelim.c \ getline.c \ getline.h \ @@ -50,3 +52,15 @@ EXTRA_DIST = \ syslog.c \ syslog.h \ vsyslog.c + +TESTS = \ + test-current-dir-name +check_PROGRAMS = $(TESTS) + +test_current_dir_name_SOURCES = \ + test-current-dir-name.c \ + get_current_dir_name.c \ + get_current_dir_name.h \ + $(NULL) +test_current_dir_name_CPPFLAGS = -I$(srcdir) +test_current_dir_name_CFLAGS = $(WARNINGS_CFLAGS) diff --git a/plugins/floppy/Makefile.am b/plugins/floppy/Makefile.am index 33d026fa..c788382c 100644 --- a/plugins/floppy/Makefile.am +++ b/plugins/floppy/Makefile.am @@ -49,6 +49,7 @@ nbdkit_floppy_plugin_la_CPPFLAGS = \ -I$(top_srcdir)/include \ -I$(top_srcdir)/common/include \ -I$(top_srcdir)/common/regions \ + -I$(top_srcdir)/common/replacements \ -I$(top_srcdir)/common/utils \ -I. \ $(NULL) diff --git a/common/replacements/get_current_dir_name.h b/common/replacements/get_current_dir_name.h new file mode 100644 index 00000000..658d4ea5 --- /dev/null +++ b/common/replacements/get_current_dir_name.h @@ -0,0 +1,48 @@ +/* nbdkit + * Copyright (C) 2018 Red Hat Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Red Hat nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef NBDKIT_GET_CURRENT_DIR_NAME_H +#define NBDKIT_GET_CURRENT_DIR_NAME_H + +#include <config.h> + +#ifdef HAVE_GET_CURRENT_DIR_NAME + +#include <unistd.h> + +#else + +extern char *get_current_dir_name (void); + +#endif + +#endif /* NBDKIT_GET_CURRENT_DIR_NAME_H */ diff --git a/server/public.c b/server/public.c index 1f7e1af0..fce16989 100644 --- a/server/public.c +++ b/server/public.c @@ -53,7 +53,7 @@ #include "ascii-ctype.h" #include "ascii-string.h" -#include "get-current-dir-name.h" +#include "get_current_dir_name.h" #include "getline.h" #include "realpath.h" diff --git a/common/include/get-current-dir-name.h b/common/replacements/get_current_dir_name.c similarity index 92% rename from common/include/get-current-dir-name.h rename to common/replacements/get_current_dir_name.c index 09c6a0fd..72ca45f0 100644 --- a/common/include/get-current-dir-name.h +++ b/common/replacements/get_current_dir_name.c @@ -32,9 +32,6 @@ /* Implement get_current_dir_name(3) on platforms which don't have it. */ -#ifndef NBDKIT_GET_CURRENT_DIR_NAME_H -#define NBDKIT_GET_CURRENT_DIR_NAME_H - #include <config.h> #ifndef HAVE_GET_CURRENT_DIR_NAME @@ -43,7 +40,9 @@ #include <unistd.h> #include <limits.h> -static inline char * +#include "get_current_dir_name.h" + +char * get_current_dir_name (void) { char *ret; @@ -56,6 +55,5 @@ get_current_dir_name (void) return NULL; return realloc (ret, strlen (ret) + 1); } -#endif -#endif /* NBDKIT_GET_CURRENT_DIR_NAME_H */ +#endif /* !HAVE_GET_CURRENT_DIR_NAME */ diff --git a/common/include/test-current-dir-name.c b/common/replacements/test-current-dir-name.c similarity index 98% rename from common/include/test-current-dir-name.c rename to common/replacements/test-current-dir-name.c index c3ca52ad..a9bb8de0 100644 --- a/common/include/test-current-dir-name.c +++ b/common/replacements/test-current-dir-name.c @@ -40,7 +40,7 @@ #undef NDEBUG /* Keep test strong even for nbdkit built without assertions */ #include <assert.h> -#include "get-current-dir-name.h" +#include "get_current_dir_name.h" int main (void) diff --git a/plugins/floppy/virtual-floppy.c b/plugins/floppy/virtual-floppy.c index 18fd4b01..60916fc5 100644 --- a/plugins/floppy/virtual-floppy.c +++ b/plugins/floppy/virtual-floppy.c @@ -49,7 +49,7 @@ #include "byte-swapping.h" #include "cleanup.h" -#include "get-current-dir-name.h" +#include "get_current_dir_name.h" #include "regions.h" #include "rounding.h" diff --git a/.gitignore b/.gitignore index ca36d9c2..792b73c6 100644 --- a/.gitignore +++ b/.gitignore @@ -36,7 +36,6 @@ plugins/*/*.3 /common/include/test-ascii-ctype /common/include/test-ascii-string /common/include/test-byte-swapping -/common/include/test-current-dir-name /common/include/test-isaligned /common/include/test-ispowerof2 /common/include/test-iszero @@ -47,6 +46,7 @@ plugins/*/*.3 /common/protocol/generate-protostrings.sh /common/protocol/protostrings.c /common/replacements/libcompat.a +/common/replacements/test-current-dir-name /common/replacements/win32/MSG00001.bin /common/replacements/win32/nbdkit-cat.h /common/replacements/win32/nbdkit-cat.rc -- 2.27.0
--- configure.ac | 1 + common/replacements/Makefile.am | 2 + common/replacements/poll.h | 60 ++++++++++++++++ server/public.c | 2 +- server/sockets.c | 2 +- common/replacements/poll.c | 120 ++++++++++++++++++++++++++++++++ 6 files changed, 185 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 0066fc45..190d35d2 100644 --- a/configure.ac +++ b/configure.ac @@ -343,6 +343,7 @@ AC_REPLACE_FUNCS([\ getdelim \ getline \ openlog \ + poll \ realpath \ strndup \ syslog \ diff --git a/common/replacements/Makefile.am b/common/replacements/Makefile.am index 9494189b..9d1d34fa 100644 --- a/common/replacements/Makefile.am +++ b/common/replacements/Makefile.am @@ -45,6 +45,8 @@ EXTRA_DIST = \ getline.c \ getline.h \ openlog.c \ + poll.c \ + poll.h \ realpath.c \ realpath.h \ strndup.c \ diff --git a/common/replacements/poll.h b/common/replacements/poll.h new file mode 100644 index 00000000..63f20861 --- /dev/null +++ b/common/replacements/poll.h @@ -0,0 +1,60 @@ +/* nbdkit + * Copyright (C) 2020 Red Hat Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Red Hat nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef NBDKIT_POLL_H +#define NBDKIT_POLL_H + +#include <config.h> + +#ifdef HAVE_POLL + +#include_next <poll.h> + +#else + +struct pollfd { + int fd; + short events; + short revents; +}; + +#define POLLIN 0x0001 +#define POLLOUT 0x0002 +#define POLLERR 0x0008 +#define POLLHUP 0x0010 +#define POLLRDHUP 0x2000 + +extern int poll (struct pollfd *fds, int n, int timeout); + +#endif + +#endif /* NBDKIT_POLL_H */ diff --git a/server/public.c b/server/public.c index fce16989..b25842f9 100644 --- a/server/public.c +++ b/server/public.c @@ -47,7 +47,6 @@ #include <limits.h> #include <termios.h> #include <errno.h> -#include <poll.h> #include <signal.h> #include <sys/socket.h> @@ -55,6 +54,7 @@ #include "ascii-string.h" #include "get_current_dir_name.h" #include "getline.h" +#include "poll.h" #include "realpath.h" #include "internal.h" diff --git a/server/sockets.c b/server/sockets.c index f6c9643a..8da331da 100644 --- a/server/sockets.c +++ b/server/sockets.c @@ -38,7 +38,6 @@ #include <inttypes.h> #include <string.h> #include <unistd.h> -#include <poll.h> #include <errno.h> #include <assert.h> #include <sys/types.h> @@ -59,6 +58,7 @@ #include <pthread.h> #include "internal.h" +#include "poll.h" #include "utils.h" #include "vector.h" diff --git a/common/replacements/poll.c b/common/replacements/poll.c new file mode 100644 index 00000000..51531880 --- /dev/null +++ b/common/replacements/poll.c @@ -0,0 +1,120 @@ +/* nbdkit + * Copyright (C) 2020 Red Hat Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Red Hat nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* Replacement for poll for platforms which lack this function. */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> + +#ifndef HAVE_POLL + +#include "poll.h" + +#ifdef WIN32 + +#include <winsock2.h> +#include <ws2tcpip.h> +#include <windows.h> +#include <errno.h> + +/* This is provided by common/utils which hasn't been compiled yet. + * Programs using the poll replacement will need to link to + * libutils.la. XXX + */ +extern int translate_winsock_error (const char *fn, int err); + +/* Windows doesn't have poll. It has something called WSAPoll in + * Winsock, but even Microsoft admit it is broken. Gnulib contains an + * elaborate emulation of poll written by Paolo Bonzini, but it's + * distributed under an incompatible license. However Winsock has + * select so we can write a simple (but slow) emulation of poll using + * select. + */ +int +poll (struct pollfd *fds, int n, int timeout) +{ + int i, r; + fd_set readfds, writefds; + struct timeval tv, *tvp; + + /* https://docs.microsoft.com/en-us/windows/win32/winsock/maximum-number-of-soc... */ + if (n >= 64) { + errno = EINVAL; + return -1; + } + + FD_ZERO (&readfds); + FD_ZERO (&writefds); + + for (i = 0; i < n; ++i) { + if (fds[i].events & POLLIN) + FD_SET (fds[i].fd, &readfds); + if (fds[i].events & POLLOUT) + FD_SET (fds[i].fd, &writefds); + fds[i].revents = 0; + } + + if (timeout >= 0) { + tv.tv_sec = timeout / 1000; + tv.tv_usec = timeout % 1000; + tvp = &tv; + } + else + tvp = NULL; + + /* Windows ignores the nfds parameter of select. */ + r = select (0, &readfds, &writefds, NULL, tvp); + if (r == -1) { + errno = translate_winsock_error ("select", WSAGetLastError ()); + return -1; + } + + r = 0; + for (i = 0; i < n; ++i) { + if (FD_ISSET (fds[i].fd, &readfds)) + fds[i].revents |= POLLIN; + if (FD_ISSET (fds[i].fd, &writefds)) + fds[i].revents |= POLLOUT; + if (fds[i].revents != 0) + r++; + } + + return r; +} + +#else /* !WIN32 */ +#error "no replacement poll is available on this platform" +#endif + +#endif /* !HAVE_POLL */ -- 2.27.0
--- configure.ac | 2 + common/replacements/Makefile.am | 4 ++ plugins/partitioning/Makefile.am | 2 + common/replacements/fdatasync.h | 44 +++++++++++++++++++ common/replacements/fsync.h | 44 +++++++++++++++++++ common/replacements/fdatasync.c | 51 ++++++++++++++++++++++ common/replacements/fsync.c | 66 +++++++++++++++++++++++++++++ plugins/partitioning/partitioning.c | 5 +-- 8 files changed, 214 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 190d35d2..c21855d8 100644 --- a/configure.ac +++ b/configure.ac @@ -339,6 +339,8 @@ AC_CHECK_FUNCS([\ dnl Replacement functions that we provide for some platforms. AC_CONFIG_LIBOBJ_DIR([common/replacements]) AC_REPLACE_FUNCS([\ + fdatasync \ + fsync \ get_current_dir_name \ getdelim \ getline \ diff --git a/common/replacements/Makefile.am b/common/replacements/Makefile.am index 9d1d34fa..bd884e0a 100644 --- a/common/replacements/Makefile.am +++ b/common/replacements/Makefile.am @@ -39,6 +39,10 @@ libcompat_la_SOURCES = libcompat_la_LIBADD = $(LTLIBOBJS) EXTRA_DIST = \ + fdatasync.c \ + fdatasync.h \ + fsync.c \ + fsync.h \ get_current_dir_name.c \ get_current_dir_name.h \ getdelim.c \ diff --git a/plugins/partitioning/Makefile.am b/plugins/partitioning/Makefile.am index d8cf9e29..9540d6f6 100644 --- a/plugins/partitioning/Makefile.am +++ b/plugins/partitioning/Makefile.am @@ -49,6 +49,7 @@ nbdkit_partitioning_plugin_la_CPPFLAGS = \ -I$(top_srcdir)/common/gpt \ -I$(top_srcdir)/common/include \ -I$(top_srcdir)/common/regions \ + -I$(top_srcdir)/common/replacements \ -I$(top_srcdir)/common/utils \ -I. \ $(NULL) @@ -61,6 +62,7 @@ nbdkit_partitioning_plugin_la_LIBADD = \ $(top_builddir)/common/gpt/libgpt.la \ $(top_builddir)/common/regions/libregions.la \ $(top_builddir)/common/utils/libutils.la \ + $(top_builddir)/common/replacements/libcompat.la \ $(NULL) if HAVE_POD diff --git a/common/replacements/fdatasync.h b/common/replacements/fdatasync.h new file mode 100644 index 00000000..426e0612 --- /dev/null +++ b/common/replacements/fdatasync.h @@ -0,0 +1,44 @@ +/* nbdkit + * Copyright (C) 2019-2020 Red Hat Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Red Hat nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef NBDKIT_FDATASYNC_H +#define NBDKIT_FDATASYNC_H + +#include <config.h> + +#include <unistd.h> + +#ifndef HAVE_FDATASYNC +extern int fdatasync (int fd); +#endif + +#endif /* NBDKIT_FDATASYNC_H */ diff --git a/common/replacements/fsync.h b/common/replacements/fsync.h new file mode 100644 index 00000000..5561205d --- /dev/null +++ b/common/replacements/fsync.h @@ -0,0 +1,44 @@ +/* nbdkit + * Copyright (C) 2019-2020 Red Hat Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Red Hat nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef NBDKIT_FSYNC_H +#define NBDKIT_FSYNC_H + +#include <config.h> + +#include <unistd.h> + +#ifndef HAVE_FSYNC +extern int fsync (int fd); +#endif + +#endif /* NBDKIT_FSYNC_H */ diff --git a/common/replacements/fdatasync.c b/common/replacements/fdatasync.c new file mode 100644 index 00000000..1487aad8 --- /dev/null +++ b/common/replacements/fdatasync.c @@ -0,0 +1,51 @@ +/* nbdkit + * Copyright (C) 2019-2020 Red Hat Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Red Hat nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* Replacement for fdatasync for platforms which lack this function. */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> + +#ifndef HAVE_FDATASYNC + +#include "fsync.h" +#include "fdatasync.h" + +int +fdatasync (int fd) +{ + return fsync (fd); +} + +#endif /* !HAVE_FDATASYNC */ diff --git a/common/replacements/fsync.c b/common/replacements/fsync.c new file mode 100644 index 00000000..090532cd --- /dev/null +++ b/common/replacements/fsync.c @@ -0,0 +1,66 @@ +/* nbdkit + * Copyright (C) 2019-2020 Red Hat Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Red Hat nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* Replacement for fsync for platforms which lack this function. */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <errno.h> + +#ifndef HAVE_FSYNC + +#include "fsync.h" + +#ifdef WIN32 + +/* Replacement fsync for Win32. */ + +#include <windows.h> + +int +fsync (int fd) +{ + if (!FlushFileBuffers (_get_osfhandle (fd))) { + nbdkit_debug ("FlushFileBuffers: error %d", GetLastError ()); + errno = EIO; + return -1; + } + return 0; +} + +#else /* !WIN32 */ +#error "no replacement fsync is available on this platform" +#endif + +#endif /* !HAVE_FSYNC */ diff --git a/plugins/partitioning/partitioning.c b/plugins/partitioning/partitioning.c index 5e963026..79b56dd6 100644 --- a/plugins/partitioning/partitioning.c +++ b/plugins/partitioning/partitioning.c @@ -50,6 +50,7 @@ #include "ascii-string.h" #include "byte-swapping.h" +#include "fdatasync.h" #include "isaligned.h" #include "iszero.h" #include "rounding.h" @@ -59,10 +60,6 @@ #include "regions.h" #include "virtual-disk.h" -#ifndef HAVE_FDATASYNC -#define fdatasync fsync -#endif - /* Debug flag: -D partitioning.regions=1: Print the regions table. */ int partitioning_debug_regions; -- 2.27.0
--- configure.ac | 2 + common/replacements/Makefile.am | 4 ++ common/replacements/pread.h | 44 ++++++++++++++++++ common/replacements/pwrite.h | 44 ++++++++++++++++++ common/replacements/pread.c | 79 +++++++++++++++++++++++++++++++++ common/replacements/pwrite.c | 77 ++++++++++++++++++++++++++++++++ 6 files changed, 250 insertions(+) diff --git a/configure.ac b/configure.ac index c21855d8..dd536258 100644 --- a/configure.ac +++ b/configure.ac @@ -346,6 +346,8 @@ AC_REPLACE_FUNCS([\ getline \ openlog \ poll \ + pread \ + pwrite \ realpath \ strndup \ syslog \ diff --git a/common/replacements/Makefile.am b/common/replacements/Makefile.am index bd884e0a..cd62fbfc 100644 --- a/common/replacements/Makefile.am +++ b/common/replacements/Makefile.am @@ -51,6 +51,10 @@ EXTRA_DIST = \ openlog.c \ poll.c \ poll.h \ + pread.c \ + pread.h \ + pwrite.c \ + pwrite.h \ realpath.c \ realpath.h \ strndup.c \ diff --git a/common/replacements/pread.h b/common/replacements/pread.h new file mode 100644 index 00000000..cf90c330 --- /dev/null +++ b/common/replacements/pread.h @@ -0,0 +1,44 @@ +/* nbdkit + * Copyright (C) 2019-2020 Red Hat Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Red Hat nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef NBDKIT_PREAD_H +#define NBDKIT_PREAD_H + +#include <config.h> + +#include <unistd.h> + +#ifndef HAVE_PREAD +extern ssize_t pread (int fd, void *buf, size_t count, off_t offset); +#endif + +#endif /* NBDKIT_PREAD_H */ diff --git a/common/replacements/pwrite.h b/common/replacements/pwrite.h new file mode 100644 index 00000000..bf02c7df --- /dev/null +++ b/common/replacements/pwrite.h @@ -0,0 +1,44 @@ +/* nbdkit + * Copyright (C) 2019-2020 Red Hat Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Red Hat nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef NBDKIT_PWRITE_H +#define NBDKIT_PWRITE_H + +#include <config.h> + +#include <unistd.h> + +#ifndef HAVE_PWRITE +extern ssize_t pwrite (int fd, const void *buf, size_t count, off_t offset); +#endif + +#endif /* NBDKIT_PWRITE_H */ diff --git a/common/replacements/pread.c b/common/replacements/pread.c new file mode 100644 index 00000000..065503ed --- /dev/null +++ b/common/replacements/pread.c @@ -0,0 +1,79 @@ +/* nbdkit + * Copyright (C) 2019-2020 Red Hat Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Red Hat nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* Replacement for pread for platforms which lack this function. */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> +#include <errno.h> + +#ifndef HAVE_PREAD + +#include "pread.h" + +#ifdef WIN32 + +/* Replacement pread for Win32. */ + +#include <windows.h> + +ssize_t +pread (int fd, void *buf, size_t count, off_t offset) +{ + DWORD r; + OVERLAPPED ovl; + + memset (&ovl, 0, sizeof ovl); + /* Seriously WTF Windows? */ + ovl.Offset = offset & 0xffffffff; + ovl.OffsetHigh = offset >> 32; + + /* XXX Will fail weirdly if count is larger than 32 bits. */ + if (!ReadFile (_get_osfhandle (fd), buf, count, &r, &ovl)) { + if (GetLastError () == ERROR_HANDLE_EOF) + return 0; + nbdkit_debug ("ReadFile: error %d", GetLastError ()); + errno = EIO; + return -1; + } + + return r; +} + +#else /* !WIN32 */ +#error "no replacement pread is available on this platform" +#endif + +#endif /* !HAVE_PREAD */ diff --git a/common/replacements/pwrite.c b/common/replacements/pwrite.c new file mode 100644 index 00000000..69cffbab --- /dev/null +++ b/common/replacements/pwrite.c @@ -0,0 +1,77 @@ +/* nbdkit + * Copyright (C) 2019-2020 Red Hat Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Red Hat nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* Replacement for pwrite for platforms which lack this function. */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <assert.h> +#include <errno.h> + +#ifndef HAVE_PWRITE + +#include "pwrite.h" + +#ifdef WIN32 + +/* Replacement pwrite for Win32. */ + +#include <windows.h> + +ssize_t +pwrite (int fd, const void *buf, size_t count, off_t offset) +{ + DWORD r; + OVERLAPPED ovl; + + memset (&ovl, 0, sizeof ovl); + /* Seriously WTF Windows? */ + ovl.Offset = offset & 0xffffffff; + ovl.OffsetHigh = offset >> 32; + + /* XXX Will fail weirdly if count is larger than 32 bits. */ + if (!WriteFile (_get_osfhandle (fd), buf, count, &r, &ovl)) { + nbdkit_debug ("WriteFile: error %d", GetLastError ()); + errno = EIO; + return -1; + } + + return r; +} + +#else /* !WIN32 */ +#error "no replacement pwrite is available on this platform" +#endif + +#endif /* !HAVE_PWRITE */ -- 2.27.0
This is a partial port of nbdkit to Windows using native APIs. On Linux we can use mingw-w64 and Wine to cross-compile and run the server. There are many missing or partially implemented things in this port, see TODO for a mostly complete list. --- include/nbdkit-common.h | 11 ++ configure.ac | 28 +++- common/utils/Makefile.am | 31 +++++ server/Makefile.am | 22 ++++ server/internal.h | 10 +- common/utils/windows-compat.h | 133 +++++++++++++++++++ server/background.c | 16 +++ server/captive.c | 20 ++- server/connections.c | 26 +++- server/crypto.c | 11 +- server/main.c | 74 ++++++++++- server/plugins.c | 3 + server/public.c | 63 ++++++++- server/quit.c | 34 +++++ server/signals.c | 13 ++ server/socket-activation.c | 12 ++ server/sockets.c | 81 +++++++++++- server/usergroup.c | 25 +++- common/utils/utils.c | 36 +++++- common/utils/windows-compat.c | 221 ++++++++++++++++++++++++++++++++ common/utils/windows-errors.txt | 105 +++++++++++++++ .gitignore | 3 + README | 49 +++++++ TODO | 35 ++++- common-rules.mk | 2 +- 25 files changed, 1040 insertions(+), 24 deletions(-) diff --git a/include/nbdkit-common.h b/include/nbdkit-common.h index c377e18d..033362e3 100644 --- a/include/nbdkit-common.h +++ b/include/nbdkit-common.h @@ -40,7 +40,13 @@ #include <stdarg.h> #include <stdint.h> #include <errno.h> + +#if !defined(_WIN32) && !defined(__MINGW32__) && \ + !defined(__CYGWIN__) && !defined(_MSC_VER) #include <sys/socket.h> +#else +#include <ws2tcpip.h> +#endif #include <nbdkit-version.h> @@ -76,7 +82,12 @@ extern "C" { #define NBDKIT_EXTENT_HOLE (1<<0) /* Same as NBD_STATE_HOLE */ #define NBDKIT_EXTENT_ZERO (1<<1) /* Same as NBD_STATE_ZERO */ +#ifndef WIN32 #define NBDKIT_EXTERN_DECL(ret, fn, args) extern ret fn args +#else +#define NBDKIT_EXTERN_DECL(ret, fn, args) \ + extern __declspec(dllexport) ret fn args +#endif NBDKIT_EXTERN_DECL (void, nbdkit_error, (const char *msg, ...) ATTRIBUTE_FORMAT_PRINTF (1, 2)); diff --git a/configure.ac b/configure.ac index dd536258..16762f54 100644 --- a/configure.ac +++ b/configure.ac @@ -45,7 +45,7 @@ AC_USE_SYSTEM_EXTENSIONS dnl NB: Do not [quote] this parameter. AM_INIT_AUTOMAKE(foreign) AC_PROG_LIBTOOL -LT_INIT +LT_INIT([win32-dll]) dnl List of plugins and filters. lang_plugins="\ @@ -313,11 +313,21 @@ AC_CHECK_HEADERS([\ alloca.h \ byteswap.h \ endian.h \ + grp.h \ + netdb.h \ + netinet/in.h \ + netinet/tcp.h \ + pwd.h \ + termios.h \ stdatomic.h \ + syslog.h \ sys/endian.h \ sys/mman.h \ sys/prctl.h \ - sys/procctl.h]) + sys/procctl.h \ + sys/socket.h \ + sys/un.h \ + sys/wait.h]) AC_CHECK_HEADERS([linux/vm_sockets.h], [], [], [#include <sys/socket.h>]) @@ -332,6 +342,7 @@ AC_CHECK_FUNCS([\ mlockall \ munlock \ open_memstream \ + pipe \ pipe2 \ ppoll \ posix_fadvise]) @@ -472,6 +483,7 @@ AC_MSG_CHECKING([if the target is Windows]) AS_CASE([$host_os], [mingw*|msys*], [ is_windows=yes + LIBS="$LIBS -lmsvcrt -lkernel32 -luser32" NO_UNDEFINED_ON_WINDOWS="-no-undefined" ], [is_windows=no] @@ -480,12 +492,20 @@ AC_MSG_RESULT([$is_windows]) AC_SUBST([NO_UNDEFINED_ON_WINDOWS]) AM_CONDITIONAL([IS_WINDOWS],[test "x$is_windows" = "xyes"]) -dnl For Windows, look for the mc/windmc utility. -dnl XXX Do we need to check for mc.exe as well? AS_IF([test "x$is_windows" = "xyes"],[ + dnl For Windows, look for the mc/windmc utility. + dnl XXX Do we need to check for mc.exe as well? AC_CHECK_TOOLS([MC],[windmc mc],[no]) AS_IF([test "x$MC" = "xno"], [AC_MSG_ERROR([mc/windmc utility must be available when compiling for Windows])]) + + dnl On Windows look for dlltool. + AC_CHECK_TOOLS([DLLTOOL],[dlltool],[no]) + AS_IF([test "x$DLLTOOL" = "xno"], + [AC_MSG_ERROR([dlltool utility must be available when compiling for Windows])]) + + dnl On Windows we require winsock2. + AC_CHECK_LIB([ws2_32], [socket]) ]) AC_SEARCH_LIBS([getaddrinfo], [network socket]) diff --git a/common/utils/Makefile.am b/common/utils/Makefile.am index a621790a..3175e37d 100644 --- a/common/utils/Makefile.am +++ b/common/utils/Makefile.am @@ -43,6 +43,9 @@ libutils_la_SOURCES = \ utils.h \ vector.c \ vector.h \ + windows-compat.h \ + windows-compat.c \ + windows-errors.c \ $(NULL) libutils_la_CPPFLAGS = \ -I$(top_srcdir)/include \ @@ -55,6 +58,34 @@ libutils_la_LIBADD = \ $(PTHREAD_LIBS) \ $(NULL) +# Generate the code to map Winsock errors to errno codes. +BUILT_SOURCES = windows-errors.c +windows-errors.c: windows-errors.txt + @rm -f $@ $@-t + @echo '/* Generated from windows-errors.txt */' > $@-t + @echo '#include <nbdkit-plugin.h>' >> $@-t + @echo '#ifdef WIN32' >> $@-t + @echo '#include <winsock2.h>' >> $@-t + @echo '#include <ws2tcpip.h>' >> $@-t + @echo '#include <windows.h>' >> $@-t + @echo '#include <errno.h>' >> $@-t + @echo 'int' >> $@-t + @echo 'translate_winsock_error (const char *fn, int err) {' >> $@-t +# Always log the original error. + @echo ' nbdkit_debug ("%s: winsock error %d", fn, err);' >> $@-t + @echo ' switch (err) {' >> $@-t + @$(SED) -e '/^#/d' \ + -e '/^$$/d' \ + -e 's/\(.*\)[[:space:]][[:space:]]*\(.*\)/#if defined(\1) \&\& defined(\2)\n case \1: return \2;\n#endif/' \ + < $< >> $@-t + @echo ' default:' >> $@-t + @echo ' return err > 10000 && err < 10025 ? err - 10000 : EINVAL;' >> $@-t + @echo ' }' >> $@-t + @echo '}' >> $@-t + @echo '#endif /* WIN32 */' >> $@-t + mv $@-t $@ + chmod -w $@ + # Unit tests. TESTS = test-quotes test-vector diff --git a/server/Makefile.am b/server/Makefile.am index d7150f52..11b3042e 100644 --- a/server/Makefile.am +++ b/server/Makefile.am @@ -115,6 +115,28 @@ nbdkit_LDFLAGS += -Wl,--version-script=$(srcdir)/nbdkit.syms endif endif +if IS_WINDOWS +# On Windows, generate an import library so that plugins can link +# against the executable. +# https://stackoverflow.com/a/18147774 +# https://sourceforge.net/p/mingw/mailman/mingw-users/thread/43694A03.2050503%... +# https://stackoverflow.com/questions/20007973/how-do-i-generate-an-import-lib... + +lib_LIBRARIES = libnbdkit.a + +libnbdkit.a: nbdkit$(EXEEXT) nbdkit.def + $(LIBTOOL) --mode=execute \ + $(DLLTOOL) -v $< -D nbdkit.exe -d nbdkit.def -l $@ + +nbdkit.def: nbdkit.syms + rm -f $@ $@-t + echo '; Generated from $<' > $@-t + echo 'EXPORTS' >> $@-t + $(SED) -n -e 's/.*\(nbdkit_[a-z0-9_]*\);.*/\t\1/p' < $< >> $@-t + mv $@-t $@ + chmod 0444 $@ +endif + # synopsis.c is generated from docs/synopsis.txt where it is also # used to generate the man page. It is included in main.c. diff --git a/server/internal.h b/server/internal.h index d043225a..d04a32cf 100644 --- a/server/internal.h +++ b/server/internal.h @@ -36,9 +36,12 @@ #include <stdbool.h> #include <stddef.h> #include <stdarg.h> -#include <sys/socket.h> #include <pthread.h> +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif + #define NBDKIT_API_VERSION 2 #define NBDKIT_INTERNAL #include "nbdkit-plugin.h" @@ -47,6 +50,7 @@ #include "nbd-protocol.h" #include "unix-path-max.h" #include "vector.h" +#include "windows-compat.h" /* Define unlikely macro, but only for GCC. These are used to move * debug and error handling code out of hot paths. @@ -147,7 +151,11 @@ extern struct backend *top; /* quit.c */ extern volatile int quit; +#ifndef WIN32 extern int quit_fd; +#else +extern HANDLE quit_fd; +#endif extern void set_up_quit_pipe (void); extern void close_quit_pipe (void); extern void handle_quit (int sig); diff --git a/common/utils/windows-compat.h b/common/utils/windows-compat.h new file mode 100644 index 00000000..74241a19 --- /dev/null +++ b/common/utils/windows-compat.h @@ -0,0 +1,133 @@ +/* nbdkit + * Copyright (C) 2020 Red Hat Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Red Hat nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef NBDKIT_WINDOWS_COMPAT_H +#define NBDKIT_WINDOWS_COMPAT_H + +#ifdef WIN32 + +#include <config.h> + +#include <winsock2.h> +#include <ws2tcpip.h> +#include <windows.h> + +#include <errno.h> + +/* Windows doesn't have O_CLOEXEC, but it also doesn't have file + * descriptors that can be inherited across exec. Similarly for + * O_NOCTTY. + */ +#ifndef O_CLOEXEC +#define O_CLOEXEC 0 +#endif +#ifndef O_NOCTTY +#define O_NOCTTY 0 +#endif + +/* AI_ADDRCONFIG is not available on Windows. It enables a rather + * obscure feature of getaddrinfo to do with IPv6. + */ +#ifndef AI_ADDRCONFIG +#define AI_ADDRCONFIG 0 +#endif + +/* Windows <errno.h> lacks certain errnos, so replace them here as + * best we can. + */ +#ifndef EBADMSG +#define EBADMSG EPROTO +#endif +#ifndef ESHUTDOWN +#define ESHUTDOWN ECONNABORTED +#endif + +/* This generated function translates Winsock errors into errno codes. */ +extern int translate_winsock_error (const char *fn, int err); + +/* Add wrappers around the Winsock syscalls that nbdkit uses. */ +extern int win_accept (int fd, struct sockaddr *addr, socklen_t *len); +extern int win_bind (int fd, const struct sockaddr *addr, socklen_t len); +extern int win_closesocket (int fd); +extern int win_getpeername (int fd, struct sockaddr *addr, socklen_t *len); +extern int win_listen (int fd, int backlog); +extern int win_getsockopt (int fd, int level, int optname, + void *optval, socklen_t *optlen); +extern int win_recv (int fd, void *buf, size_t len, int flags); +extern int win_setsockopt (int fd, int level, int optname, + const void *optval, socklen_t optlen); +extern int win_socket (int domain, int type, int protocol); +extern int win_send (int fd, const void *buf, size_t len, int flags); + +#define accept win_accept +#define bind win_bind +#define closesocket win_closesocket +#define getpeername win_getpeername +#define listen win_listen +#define getsockopt win_getsockopt +#define recv win_recv +#define setsockopt win_setsockopt +#define socket win_socket +#define send win_send + +/* Windows has strange names for these functions. */ +#define dup _dup +#define dup2 _dup2 + +/* Unfortunately quite commonly used at the moment. Make it a common + * macro so we can easily find places which need porting. + * + * Note: Don't use this for things which can never work on Windows + * (eg. Unix socket support). Those should just give regular errors. + */ +#define NOT_IMPLEMENTED_ON_WINDOWS(feature) \ + do { \ + fprintf (stderr, "nbdkit: %s is not implemented for Windows.\n", feature); \ + fprintf (stderr, "You can help by contributing to the Windows port, see\n"); \ + fprintf (stderr, "nbdkit README in the source for how to contribute.\n"); \ + exit (EXIT_FAILURE); \ + } while (0) + +#else /* !WIN32 */ + +/* Windows doesn't have a generic function for closing anything, + * instead you have to call closesocket on a SOCKET object. We would + * like to #define close to point to the Windows alternative above, + * but that's not possible because it breaks things like + * backend->close. So instead the server code must call closesocket() + * on anything that might be a socket. + */ +#define closesocket close + +#endif /* !WIN32 */ + +#endif /* NBDKIT_WINDOWS_COMPAT_H */ diff --git a/server/background.c b/server/background.c index 72ab1ef6..e3507d5c 100644 --- a/server/background.c +++ b/server/background.c @@ -44,6 +44,8 @@ /* True if we forked into the background (used to control log messages). */ bool forked_into_background; +#ifndef WIN32 + /* Run as a background process. If foreground is set (ie. -f or * equivalent) then this does nothing. Otherwise it forks into the * background and sets forked_into_background. @@ -79,3 +81,17 @@ fork_into_background (void) forked_into_background = true; debug ("forked into background (new pid = %d)", getpid ()); } + +#else /* WIN32 */ + +void +fork_into_background (void) +{ + if (foreground) + return; + + fprintf (stderr, "nbdkit: You must use the -f option on Windows.\n"); + NOT_IMPLEMENTED_ON_WINDOWS ("daemonizing"); +} + +#endif /* WIN32 */ diff --git a/server/captive.c b/server/captive.c index a8947d7c..19e50b07 100644 --- a/server/captive.c +++ b/server/captive.c @@ -38,14 +38,19 @@ #include <string.h> #include <unistd.h> #include <sys/types.h> -#include <sys/wait.h> #include <signal.h> #include <assert.h> +#ifdef HAVE_SYS_WAIT_H +#include <sys/wait.h> +#endif + #include "utils.h" #include "internal.h" +#ifndef WIN32 + /* Handle the --run option. If run is NULL, does nothing. If run is * not NULL then run nbdkit as a captive subprocess of the command. */ @@ -208,3 +213,16 @@ run_command (void) debug ("forked into background (new pid = %d)", getpid ()); } + +#else /* WIN32 */ + +void +run_command (void) +{ + if (!run) + return; + + NOT_IMPLEMENTED_ON_WINDOWS ("--run"); +} + +#endif /* WIN32 */ diff --git a/server/connections.c b/server/connections.c index a3dd4ca7..96b72257 100644 --- a/server/connections.c +++ b/server/connections.c @@ -38,10 +38,13 @@ #include <inttypes.h> #include <string.h> #include <unistd.h> -#include <sys/socket.h> #include <fcntl.h> #include <assert.h> +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif + #include "internal.h" #include "utils.h" @@ -268,6 +271,7 @@ new_connection (int sockin, int sockout, int nworkers) goto error2; } #else +#ifdef HAVE_PIPE /* If we were fully parallel, then this function could be * accepting connections in one thread while another thread could * be in a plugin trying to fork. But plugins.c forced @@ -296,16 +300,23 @@ new_connection (int sockin, int sockout, int nworkers) goto error2; } unlock_request (); +#else /* !HAVE_PIPE2 && !HAVE_PIPE */ + /* Windows has neither pipe2 nor pipe. XXX */ +#endif #endif } conn->sockin = sockin; conn->sockout = sockout; conn->recv = raw_recv; +#ifndef WIN32 if (getsockopt (sockout, SOL_SOCKET, SO_TYPE, &opt, &optlen) == 0) conn->send = raw_send_socket; else conn->send = raw_send_other; +#else + conn->send = raw_send_socket; +#endif conn->close = raw_close; threadlocal_set_conn (conn); @@ -439,7 +450,16 @@ raw_recv (void *vbuf, size_t len) bool first_read = true; while (len > 0) { + /* On Unix we want to use read(2) here because that allows us to + * read from non-sockets (think: nbdkit -s). In particular this + * makes fuzzing possible. However this is not possible on + * Windows where we must use recv. + */ +#ifndef WIN32 r = read (sock, buf, len); +#else + r = recv (sock, buf, len, 0); +#endif if (r == -1) { if (errno == EINTR || errno == EAGAIN) continue; @@ -469,7 +489,7 @@ raw_close (void) GET_CONN; if (conn->sockin >= 0) - close (conn->sockin); + closesocket (conn->sockin); if (conn->sockout >= 0 && conn->sockin != conn->sockout) - close (conn->sockout); + closesocket (conn->sockout); } diff --git a/server/crypto.c b/server/crypto.c index 0d3d4e8c..a3f8682f 100644 --- a/server/crypto.c +++ b/server/crypto.c @@ -161,7 +161,12 @@ start_certificates (void) const char *home; CLEANUP_FREE char *path = NULL; - if (geteuid () != 0) { +#ifndef WIN32 +#define RUNNING_AS_NON_ROOT_FOR_CERTIFICATES_DIR (geteuid () != 0) +#else +#define RUNNING_AS_NON_ROOT_FOR_CERTIFICATES_DIR 0 +#endif + if (RUNNING_AS_NON_ROOT_FOR_CERTIFICATES_DIR) { home = getenv ("HOME"); if (home) { if (asprintf (&path, "%s/.pki/%s", home, PACKAGE_NAME) == -1) { @@ -407,9 +412,9 @@ crypto_close (void) gnutls_bye (session, GNUTLS_SHUT_RDWR); if (sockin >= 0) - close (sockin); + closesocket (sockin); if (sockout >= 0 && sockin != sockout) - close (sockout); + closesocket (sockout); gnutls_deinit (session); conn->crypto_session = NULL; diff --git a/server/main.c b/server/main.c index 78da5ee8..fa5073d6 100644 --- a/server/main.c +++ b/server/main.c @@ -44,12 +44,15 @@ #include <assert.h> #include <sys/types.h> #include <sys/stat.h> -#include <sys/socket.h> #ifdef HAVE_SYS_MMAN_H #include <sys/mman.h> #endif +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif + #ifdef HAVE_LINUX_VM_SOCKETS_H #include <linux/vm_sockets.h> #endif @@ -61,6 +64,7 @@ #include "ascii-string.h" #include "exit-with-parent.h" #include "nbd-protocol.h" +#include "realpath.h" #include "strndup.h" #include "syslog.h" @@ -79,6 +83,7 @@ static void write_pidfile (void); static bool is_config_key (const char *key, size_t len); static void error_if_stdio_closed (void); static void switch_stdio (void); +static void winsock_init (void); struct debug_flag *debug_flags; /* -D */ bool exit_with_parent; /* --exit-with-parent */ @@ -136,7 +141,25 @@ display_version (void) static void dump_config (void) { - CLEANUP_FREE char *binary = realpath ("/proc/self/exe", NULL); + CLEANUP_FREE char *binary = NULL; + +#ifdef __linux__ + binary = realpath ("/proc/self/exe", NULL); +#else +#ifdef WIN32 + /* GetModuleFileNameA has a crappy interface that prevents us from + * getting the length of the path so we just have to guess at an + * upper limit here. It will at least truncate it properly with \0. + * _get_pgmptr would be a better alternative except that it isn't + * implemented in MinGW. XXX + */ + binary = malloc (256); + if (!GetModuleFileNameA (NULL, binary, 256)) { + free (binary); + binary = NULL; + } +#endif +#endif if (binary != NULL) printf ("%s=%s\n", "binary", binary); @@ -188,6 +211,7 @@ main (int argc, char *argv[]) const char *magic_config_key; error_if_stdio_closed (); + winsock_init (); #if !ENABLE_LIBFUZZER threadlocal_init (); @@ -405,6 +429,16 @@ main (int argc, char *argv[]) exit (EXIT_FAILURE); } listen_stdin = true; +#ifdef WIN32 + /* This could be implemented with a bit of work. The problem + * currently is that we try to use recv() on the stdio file + * descriptor which winsock does not support (nor Linux in + * fact). We would need to implement a test to see if the file + * descriptor is a socket or not and use either read or recv as + * appropriate. + */ + NOT_IMPLEMENTED_ON_WINDOWS ("-s"); +#endif break; case 't': @@ -728,6 +762,8 @@ main (int argc, char *argv[]) return EXIT_SUCCESS; } +#ifndef WIN32 + /* Implementation of '-U -' */ static char * make_random_fifo (void) @@ -760,6 +796,16 @@ make_random_fifo (void) return sock; } +#else /* WIN32 */ + +static char * +make_random_fifo (void) +{ + NOT_IMPLEMENTED_ON_WINDOWS ("-U -"); +} + +#endif /* WIN32 */ + static struct backend * open_plugin_so (size_t i, const char *name, int short_name) { @@ -1001,6 +1047,7 @@ is_config_key (const char *key, size_t len) static void error_if_stdio_closed (void) { +#ifdef F_GETFL if (fcntl (STDERR_FILENO, F_GETFL) == -1) { /* Nowhere we can report the error. Oh well. */ exit (EXIT_FAILURE); @@ -1010,6 +1057,7 @@ error_if_stdio_closed (void) perror ("expecting stdin/stdout to be opened"); exit (EXIT_FAILURE); } +#endif } /* Sanitize stdin/stdout to /dev/null, after saving the originals @@ -1024,6 +1072,7 @@ error_if_stdio_closed (void) static void switch_stdio (void) { +#if defined(F_DUPFD_CLOEXEC) || defined(F_DUPFD) fflush (stdin); fflush (NULL); if (listen_stdin || run) { @@ -1041,6 +1090,8 @@ switch_stdio (void) exit (EXIT_FAILURE); } } +#endif +#ifndef WIN32 close (STDIN_FILENO); close (STDOUT_FILENO); if (open ("/dev/null", O_RDONLY) != STDIN_FILENO || @@ -1048,4 +1099,23 @@ switch_stdio (void) perror ("open"); exit (EXIT_FAILURE); } +#endif +} + +/* On Windows the Winsock library must be initialized early. + * https://docs.microsoft.com/en-us/windows/win32/winsock/initializing-winsock + */ +static void +winsock_init (void) +{ +#ifdef WIN32 + WSADATA wsaData; + int result; + + result = WSAStartup (MAKEWORD (2, 2), &wsaData); + if (result != 0) { + fprintf (stderr, "WSAStartup failed: %d\n", result); + exit (EXIT_FAILURE); + } +#endif } diff --git a/server/plugins.c b/server/plugins.c index 218764da..736154b8 100644 --- a/server/plugins.c +++ b/server/plugins.c @@ -39,7 +39,10 @@ #include <inttypes.h> #include <assert.h> #include <errno.h> + +#ifdef HAVE_SYS_SOCKET_H #include <sys/socket.h> +#endif #include "internal.h" #include "minmax.h" diff --git a/server/public.c b/server/public.c index b25842f9..98086d72 100644 --- a/server/public.c +++ b/server/public.c @@ -45,10 +45,21 @@ #include <string.h> #include <unistd.h> #include <limits.h> -#include <termios.h> #include <errno.h> #include <signal.h> + +#ifdef HAVE_TERMIOS_H +#include <termios.h> +#endif + +#ifdef HAVE_SYS_SOCKET_H #include <sys/socket.h> +#endif + +#ifdef WIN32 +/* For nanosleep on Windows. */ +#include <pthread_time.h> +#endif #include "ascii-ctype.h" #include "ascii-string.h" @@ -468,6 +479,8 @@ nbdkit_read_password (const char *value, char **password) return 0; } +#ifndef WIN32 + typedef struct termios echo_mode; static void @@ -487,6 +500,37 @@ echo_restore (const echo_mode *old_mode) tcsetattr (STDIN_FILENO, TCSAFLUSH, old_mode); } +#else /* WIN32 */ + +/* Windows implementation of tty echo off based on this: + * https://stackoverflow.com/a/1455007 + */ +typedef DWORD echo_mode; + +static void +echo_off (echo_mode *old_mode) +{ + HANDLE h_stdin; + DWORD mode; + + h_stdin = GetStdHandle (STD_INPUT_HANDLE); + GetConsoleMode (h_stdin, old_mode); + mode = *old_mode; + mode &= ~ENABLE_ECHO_INPUT; + SetConsoleMode (h_stdin, mode); +} + +static void +echo_restore (const echo_mode *old_mode) +{ + HANDLE h_stdin; + + h_stdin = GetStdHandle (STD_INPUT_HANDLE); + SetConsoleMode (h_stdin, *old_mode); +} + +#endif /* WIN32 */ + static int read_password_interactive (char **password) { @@ -546,6 +590,8 @@ read_password_interactive (char **password) return 0; } +#ifndef WIN32 + static int read_password_from_fd (const char *what, int fd, char **password) { @@ -593,6 +639,21 @@ read_password_from_fd (const char *what, int fd, char **password) return 0; } +#else /* WIN32 */ + +/* As far as I know this will never be possible on Windows, so it's a + * simple error. + */ +static int +read_password_from_fd (const char *what, int fd, char **password) +{ + nbdkit_error ("not possible to read passwords from file descriptors " + "under Windows"); + return -1; +} + +#endif /* WIN32 */ + int nbdkit_nanosleep (unsigned sec, unsigned nsec) { diff --git a/server/quit.c b/server/quit.c index 13fef437..21263fdb 100644 --- a/server/quit.c +++ b/server/quit.c @@ -48,8 +48,15 @@ * a race. */ volatile int quit; + +#ifndef WIN32 int quit_fd; static int write_quit_fd; +#else +HANDLE quit_fd; +#endif + +#ifndef WIN32 void set_up_quit_pipe (void) @@ -99,6 +106,33 @@ set_quit (void) #pragma GCC diagnostic pop } +#else /* WIN32 */ + +/* Pipes don't work well with WaitForMultipleObjectsEx in Windows. In + * any case, an Event is a better match with what we are trying to do + * here. + */ +void +set_up_quit_pipe (void) +{ + quit_fd = CreateEventA (NULL, FALSE, FALSE, NULL); +} + +void +close_quit_pipe (void) +{ + CloseHandle (quit_fd); +} + +void +set_quit (void) +{ + quit = 1; + SetEvent (quit_fd); +} + +#endif /* WIN32 */ + void handle_quit (int sig) { diff --git a/server/signals.c b/server/signals.c index d7dc17d0..f463ccd8 100644 --- a/server/signals.c +++ b/server/signals.c @@ -40,6 +40,8 @@ #include "internal.h" +#ifndef WIN32 + /* Set up signal handlers. */ void set_up_signals (void) @@ -59,3 +61,14 @@ set_up_signals (void) sa.sa_handler = SIG_IGN; sigaction (SIGPIPE, &sa, NULL); } + +#else /* WIN32 */ + +void +set_up_signals (void) +{ + signal (SIGINT, handle_quit); + signal (SIGTERM, handle_quit); +} + +#endif /* WIN32 */ diff --git a/server/socket-activation.c b/server/socket-activation.c index f273f8cc..a49e1cc0 100644 --- a/server/socket-activation.c +++ b/server/socket-activation.c @@ -42,6 +42,8 @@ #include "internal.h" +#ifndef WIN32 + /* Handle socket activation. This is controlled through special * environment variables inherited by nbdkit. Returns 0 if no socket * activation. Otherwise returns the number of FDs. See also @@ -105,3 +107,13 @@ get_socket_activation (void) return nr_fds; } + +#else /* WIN32 */ + +unsigned int +get_socket_activation (void) +{ + return 0; +} + +#endif /* WIN32 */ diff --git a/server/sockets.c b/server/sockets.c index 8da331da..4fcf3529 100644 --- a/server/sockets.c +++ b/server/sockets.c @@ -41,11 +41,26 @@ #include <errno.h> #include <assert.h> #include <sys/types.h> + +#ifdef HAVE_SYS_SOCKET_H #include <sys/socket.h> +#endif + +#ifdef HAVE_SYS_UN_H #include <sys/un.h> +#endif + +#ifdef HAVE_NETINET_IN_H #include <netinet/in.h> +#endif + +#ifdef HAVE_NETINET_TCP_H #include <netinet/tcp.h> +#endif + +#ifdef HAVE_NETDB_H #include <netdb.h> +#endif #ifdef HAVE_LINUX_VM_SOCKETS_H #include <linux/vm_sockets.h> @@ -94,6 +109,8 @@ clear_selinux_label (void) #endif } +#ifndef WIN32 + void bind_unix_socket (sockets *socks) { @@ -149,6 +166,16 @@ bind_unix_socket (sockets *socks) debug ("bound to unix socket %s", unixsocket); } +#else /* WIN32 */ + +void +bind_unix_socket (sockets *socks) +{ + NOT_IMPLEMENTED_ON_WINDOWS ("-U"); +} + +#endif /* WIN32 */ + void bind_tcpip_socket (sockets *socks) { @@ -207,7 +234,7 @@ bind_tcpip_socket (sockets *socks) if (bind (sock, a->ai_addr, a->ai_addrlen) == -1) { if (errno == EADDRINUSE) { addr_in_use = true; - close (sock); + closesocket (sock); continue; } perror ("bind"); @@ -402,7 +429,7 @@ accept_connection (int listen_sock) pthread_attr_destroy (&attrs); if (unlikely (err != 0)) { fprintf (stderr, "%s: pthread_create: %s\n", program_name, strerror (err)); - close (thread_data->sock); + closesocket (thread_data->sock); free (thread_data); return; } @@ -412,6 +439,8 @@ accept_connection (int listen_sock) */ } +#ifndef WIN32 + /* Check the list of sockets plus quit_fd until a POLLIN event occurs * on any of them. * @@ -465,6 +494,52 @@ check_sockets_and_quit_fd (const sockets *socks) } } +#else /* WIN32 */ + +static void +check_sockets_and_quit_fd (const sockets *socks) +{ + const size_t nr_socks = socks->size; + size_t i; + HANDLE h, handles[nr_socks+1]; + DWORD r; + + for (i = 0; i < nr_socks; ++i) { + h = WSACreateEvent (); + WSAEventSelect (_get_osfhandle (socks->ptr[i]), h, + FD_ACCEPT|FD_READ|FD_CLOSE); + handles[i] = h; + } + handles[nr_socks] = quit_fd; + + r = WaitForMultipleObjectsEx ((DWORD) (nr_socks+1), handles, + FALSE, INFINITE, TRUE); + debug ("WaitForMultipleObjectsEx returned %d", (int) r); + if (r == WAIT_FAILED) { + fprintf (stderr, "%s: WaitForMultipleObjectsEx: error %lu\n", + program_name, GetLastError ()); + exit (EXIT_FAILURE); + } + + for (i = 0; i < nr_socks; ++i) { + WSAEventSelect (_get_osfhandle (socks->ptr[i]), NULL, 0); + WSACloseEvent (handles[i]); + } + + if (r == WAIT_OBJECT_0 + nr_socks) /* quit_fd signalled. */ + return; + + if (r >= WAIT_OBJECT_0 && r < WAIT_OBJECT_0 + nr_socks) { + i = r - WAIT_OBJECT_0; + accept_connection (socks->ptr[i]); + return; + } + + debug ("WaitForMultipleObjectsEx: unexpected return value: %lu\n", r); +} + +#endif /* WIN32 */ + void accept_incoming_connections (const sockets *socks) { @@ -488,6 +563,6 @@ accept_incoming_connections (const sockets *socks) pthread_mutex_unlock (&count_mutex); for (i = 0; i < socks->size; ++i) - close (socks->ptr[i]); + closesocket (socks->ptr[i]); free (socks->ptr); } diff --git a/server/usergroup.c b/server/usergroup.c index 11bafceb..1bede73f 100644 --- a/server/usergroup.c +++ b/server/usergroup.c @@ -37,13 +37,21 @@ #include <stdarg.h> #include <string.h> #include <unistd.h> -#include <pwd.h> -#include <grp.h> #include <errno.h> #include <sys/types.h> +#ifdef HAVE_PWD_H +#include <pwd.h> +#endif + +#ifdef HAVE_GRP_H +#include <grp.h> +#endif + #include "internal.h" +#if defined(HAVE_PWD_H) && defined(HAVE_GRP_H) + static uid_t parseuser (const char *); static gid_t parsegroup (const char *); @@ -138,3 +146,16 @@ parsegroup (const char *id) return grp->gr_gid; } + +#else /* a platform like Windows which lacks pwd/grp functions */ + +void +change_user (void) +{ + if (!user && !group) + return; + + NOT_IMPLEMENTED_ON_WINDOWS ("--user/--group"); +} + +#endif diff --git a/common/utils/utils.c b/common/utils/utils.c index 0da54726..49204532 100644 --- a/common/utils/utils.c +++ b/common/utils/utils.c @@ -36,12 +36,20 @@ #include <stdlib.h> #include <fcntl.h> #include <unistd.h> -#include <sys/socket.h> #include <sys/types.h> + +#ifdef HAVE_SYS_SOCKET_H +#include <sys/socket.h> +#endif + +#ifdef HAVE_SYS_WAIT_H #include <sys/wait.h> +#endif #include <nbdkit-plugin.h> +#ifndef WIN32 + /* Convert exit status to nbd_error. If the exit status was nonzero * or another failure then -1 is returned. */ @@ -67,6 +75,10 @@ exit_status_to_nbd_error (int status, const char *cmd) return 0; } +#endif /* !WIN32 */ + +#ifndef WIN32 + /* Set the FD_CLOEXEC flag on the given fd, if it is non-negative. * On failure, close fd and return -1; on success, return fd. * @@ -107,6 +119,18 @@ set_cloexec (int fd) #endif } +#else /* WIN32 */ + +int +set_cloexec (int fd) +{ + return fd; +} + +#endif /* WIN32 */ + +#ifndef WIN32 + /* Set the O_NONBLOCK flag on the given fd, if it is non-negative. * On failure, close fd and return -1; on success, return fd. */ @@ -129,3 +153,13 @@ set_nonblock (int fd) } return fd; } + +#else /* WIN32 */ + +int +set_nonblock (int fd) +{ + return fd; +} + +#endif /* WIN32 */ diff --git a/common/utils/windows-compat.c b/common/utils/windows-compat.c new file mode 100644 index 00000000..355d14f0 --- /dev/null +++ b/common/utils/windows-compat.c @@ -0,0 +1,221 @@ +/* nbdkit + * Copyright (C) 2020 Red Hat Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of Red Hat nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF + * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <config.h> + +#include <stdio.h> + +#ifdef WIN32 + +#include <winsock2.h> +#include <ws2tcpip.h> +#include <windows.h> +#include <fcntl.h> +#include <errno.h> + +#include "windows-compat.h" + +#undef accept +#undef bind +#undef closesocket +#undef getpeername +#undef listen +#undef getsockopt +#undef recv +#undef setsockopt +#undef socket +#undef send + +#define GET_SOCKET_FROM_FD(fd) \ + SOCKET sk = _get_osfhandle (fd); \ + if (sk == INVALID_SOCKET) { \ + errno = EBADF; \ + return -1; \ + } + +/* Sockets are non-blocking by default. Make them blocking. This + * introduces a bunch of caveats, see: + * http://www.sockets.com/winsock.htm#Overview_BlockingNonBlocking + */ +static int +set_blocking (SOCKET sk) +{ + u_long arg = 0; + + if (ioctlsocket (sk, FIONBIO, &arg) < 0) { + errno = translate_winsock_error ("ioctlsocket", WSAGetLastError ()); + return -1; + } + return 0; +} + +int +win_accept (int fd, struct sockaddr *addr, socklen_t *len) +{ + SOCKET new_sk; + GET_SOCKET_FROM_FD (fd); + + new_sk = accept (sk, addr, len); + if (new_sk == INVALID_SOCKET) { + errno = translate_winsock_error ("accept", WSAGetLastError ()); + return -1; + } + if (set_blocking (new_sk) == -1) return -1; + return _open_osfhandle ((intptr_t) new_sk, O_RDWR|O_BINARY); +} + +int +win_bind (int fd, const struct sockaddr *addr, socklen_t len) +{ + GET_SOCKET_FROM_FD (fd); + + if (bind (sk, addr, len) < 0) { + errno = translate_winsock_error ("bind", WSAGetLastError ()); + return -1; + } + + return 0; +} + +int +win_closesocket (int fd) +{ + GET_SOCKET_FROM_FD (fd); + + if (closesocket (sk) < 0) { + errno = translate_winsock_error ("closesocket", WSAGetLastError ()); + return -1; + } + + return 0; +} + +int +win_getpeername (int fd, struct sockaddr *addr, socklen_t *len) +{ + GET_SOCKET_FROM_FD (fd); + + if (getpeername (sk, addr, len) < 0) { + errno = translate_winsock_error ("getpeername", WSAGetLastError ()); + return -1; + } + + return 0; +} + +int +win_listen (int fd, int backlog) +{ + GET_SOCKET_FROM_FD (fd); + + if (listen (sk, backlog) < 0) { + errno = translate_winsock_error ("listen", WSAGetLastError ()); + return -1; + } + + return 0; +} + +int +win_getsockopt (int fd, int level, int optname, + void *optval, socklen_t *optlen) +{ + GET_SOCKET_FROM_FD (fd); + + if (getsockopt (sk, level, optname, optval, optlen) < 0) { + errno = translate_winsock_error ("getsockopt", WSAGetLastError ()); + return -1; + } + + return 0; +} + +int +win_recv (int fd, void *buf, size_t len, int flags) +{ + int r; + GET_SOCKET_FROM_FD (fd); + + r = recv (sk, buf, len, flags); + if (r < 0) { + errno = translate_winsock_error ("recv", WSAGetLastError ()); + return -1; + } + + return r; +} + +int +win_setsockopt (int fd, int level, int optname, + const void *optval, socklen_t optlen) +{ + GET_SOCKET_FROM_FD (fd); + + if (setsockopt (sk, level, optname, optval, optlen) < 0) { + errno = translate_winsock_error ("setsockopt", WSAGetLastError ()); + return -1; + } + + return 0; +} + +int +win_socket (int domain, int type, int protocol) +{ + SOCKET sk; + + sk = WSASocket (domain, type, protocol, NULL, 0, 0); + if (sk == INVALID_SOCKET) { + errno = translate_winsock_error ("socket", WSAGetLastError ()); + return -1; + } + + if (set_blocking (sk) == -1) return -1; + return _open_osfhandle ((intptr_t) sk, O_RDWR|O_BINARY); +} + +int +win_send (int fd, const void *buf, size_t len, int flags) +{ + int r; + GET_SOCKET_FROM_FD (fd); + + r = send (sk, buf, len, flags); + if (r < 0) { + errno = translate_winsock_error ("send", WSAGetLastError ()); + return -1; + } + + return r; +} + +#endif /* WIN32 */ diff --git a/common/utils/windows-errors.txt b/common/utils/windows-errors.txt new file mode 100644 index 00000000..1a252abe --- /dev/null +++ b/common/utils/windows-errors.txt @@ -0,0 +1,105 @@ +# Winsock error to errno code mapping. +# Copyright (C) 2020 Red Hat Inc. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the name of Red Hat nor the names of its contributors may be +# used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, +# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF +# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. + +# The main reference is: +# https://docs.microsoft.com/en-us/windows/win32/winsock/windows-sockets-error... +# This was originally written by hand, but I also referenced libvirt's +# and Gnulib's choices of mappings. + +WSA_INVALID_HANDLE EBADF +WSA_NOT_ENOUGH_MEMORY ENOMEM +WSA_INVALID_PARAMETER EINVAL +WSA_OPERATION_ABORTED ECONNABORTED + +# These two are only kind of correct. +WSA_IO_INCOMPLETE EWOULDBLOCK +WSA_IO_PENDING EWOULDBLOCK + +WSAEINTR EINTR +WSAEBADF EBADF +WSAEACCES EACCES +WSAEFAULT EFAULT +WSAEINVAL EINVAL +WSAEMFILE EMFILE +WSAEWOULDBLOCK EWOULDBLOCK +WSAEINPROGRESS EINPROGRESS +WSAEALREADY EALREADY +WSAENOTSOCK ENOTSOCK +WSAEDESTADDRREQ EDESTADDRREQ +WSAEMSGSIZE EMSGSIZE +WSAEPROTOTYPE EPROTOTYPE +WSAENOPROTOOPT ENOPROTOOPT +WSAEPROTONOSUPPORT EPROTONOSUPPORT +WSAESOCKTNOSUPPORT ESOCKTNOSUPPORT +WSAEOPNOTSUPP EOPNOTSUPP +WSAEPFNOSUPPORT EPFNOSUPPORT +WSAEAFNOSUPPORT EAFNOSUPPORT +WSAEADDRINUSE EADDRINUSE +WSAEADDRNOTAVAIL EADDRNOTAVAIL +WSAENETDOWN ENETDOWN +WSAENETUNREACH ENETUNREACH +WSAENETRESET ENETRESET +WSAECONNABORTED ECONNABORTED +WSAECONNRESET ECONNRESET +WSAENOBUFS ENOBUFS +WSAEISCONN EISCONN +WSAENOTCONN ENOTCONN +WSAESHUTDOWN ESHUTDOWN +WSAETOOMANYREFS ETOOMANYREFS +WSAETIMEDOUT ETIMEDOUT +WSAECONNREFUSED ECONNREFUSED +WSAELOOP ELOOP +WSAENAMETOOLONG ENAMETOOLONG +WSAEHOSTDOWN EHOSTDOWN +WSAEHOSTUNREACH EHOSTUNREACH +WSAENOTEMPTY ENOTEMPTY + +# This really means "too many processes" but this is the closest I could find. +WSAEPROCLIM EMFILE + +WSAEUSERS EUSERS +WSAEDQUOT EDQUOT +WSAESTALE ESTALE +WSAEREMOTE EREMOTE + +# The next three are respectively: Didn't call WSAStartup, Winsock +# version is unsupported, and WSAStartup failed. +WSASYSNOTREADY EINVAL +WSAVERNOTSUPPORTED EINVAL +WSANOTINITIALISED EINVAL + +WSAEDISCON ESHUTDOWN +WSAENOMORE ESHUTDOWN +WSAECANCELLED ECANCELED + +# There are a bunch more after this but they all seem pretty obscure. +# Unknown errors are mapped to EIO and a debug message is printed so +# we have the original error. diff --git a/.gitignore b/.gitignore index 792b73c6..6919a4d7 100644 --- a/.gitignore +++ b/.gitignore @@ -52,6 +52,7 @@ plugins/*/*.3 /common/replacements/win32/nbdkit-cat.rc /common/utils/test-quotes /common/utils/test-vector +/common/utils/windows-errors.c /compile /config.cache /config.guess @@ -86,8 +87,10 @@ plugins/*/*.3 /plugins/rust/target /plugins/tmpdisk/default-command.c /podwrapper.pl +/server/libnbdkit.a /server/local/nbdkit.pc /server/nbdkit +/server/nbdkit.def /server/nbdkit.pc /server/synopsis.c /server/test-public diff --git a/README b/README index 0e295146..2bf8ce5f 100644 --- a/README +++ b/README @@ -46,6 +46,9 @@ Linux, FreeBSD, OpenBSD or Haiku and: - GNU make +(For Windows support, see the separate section at the end of this +document.) + Although it is possible to build without it, it’s recommended to enable TLS (authentication and encryption) support for which you will need: @@ -300,3 +303,49 @@ Test coverage Open your browser and examine the coverage/ directory. At the time of writing (2020-04) test coverage of the server is reasonable, but things are much worse for certain plugins and filters. + +WINDOWS +======= + +Experimentally, the server can be compiled on Windows or +cross-compiled from Linux using mingw-w64. Only a small subset of +features are available. To find out what is missing read the TODO +"Windows port". + +For the rest of this section we talk about cross-compiling for Windows +using Linux and mingw-w64. At a minimum you will need: + + mingw-w64 GCC + mingw-w64 dlfcn + mingw-w64 winpthreads + mingw-w64 gnutls (optional, but highly recommended) + mingw-w64 libxml2 (optional, but highly recommended) + wine (if you want to run it on Linux) + +Other mingw-w64 libraries may be installed which will add +functionality (see full list of requirements above), but you may end +up hitting areas we have not compiled or tested before. + +To cross compile do: + + mingw64-configure --disable-ocaml --disable-perl --disable-vddk + mingw64-make + +It is expected to fail, but check that it gets as far as building +server/nbdkit.exe. You can test if the server is working by doing: + + wine server/nbdkit.exe --dump-config + +Now try to build plugins and filters (many will not compile): + + mingw64-make -k + +To see which ones were compiled: + + find -name '*.dll' + +You can run them under Wine without installing using eg: + + wine server/nbdkit.exe -f -v \ + plugins/memory/.libs/nbdkit-memory-plugin.dll \ + size=1G diff --git a/TODO b/TODO index 89b45c72..c3314d37 100644 --- a/TODO +++ b/TODO @@ -300,8 +300,6 @@ Build-related bash-completion and ocaml add-ons into their system-wide home do not play nicely with --prefix builds for a non-root user. -* Port to Windows. - * Right now, 'make check' builds keys with an expiration of 1 year only if they don't exist, and we leave the keys around except under 'make distclean'. This leads to testsuite failures when @@ -310,6 +308,39 @@ Build-related scripts, but tweak the scripts themselves to be a no-op unless the keys don't exist or have expired. +Windows port +------------ + +Currently many features are missing, including: + +* Daemonization. This is not really applicable for Windows where you + would instead want to run nbdkit as a service using something like + SRVANY. You must use the -f option or one of the other options that + implies -f. + +* These options are all unimplemented: + --group, --log=syslog, --pidfile, --run, --selinux-label, --single + --swap, --unix, --user, --vsock + +* For possible Unix domain socket support in future see: + https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/ + +* The file plugin. The current file plugin is essentially POSIX-only. + We would like to eventually write an alternate file plugin which + uses Windows APIs. + +* Many other plugins and filters. + +* Short names for plugins and filters don't work at the moment. + +* The ./nbdkit wrapper in the top directory is not built yet. + +* errno_is_preserved should use GetLastError and/or WSAGetLastError + but currently does neither so errors from plugins are probably wrong + in many cases. + +* Most tests will fail because of the missing features above. + V3 plugin protocol ------------------ diff --git a/common-rules.mk b/common-rules.mk index 263dea98..d808db24 100644 --- a/common-rules.mk +++ b/common-rules.mk @@ -35,4 +35,4 @@ NULL = plugindir = $(libdir)/nbdkit/plugins filterdir = $(libdir)/nbdkit/filters -CLEANFILES = *~ *.cmi *.cmx *.cmxa *.so +CLEANFILES = *~ *.cmi *.cmx *.cmxa *.so *.dll -- 2.27.0
In the previous commit we built an import library on Windows (server/libnbdkit.a). This contains the stubs which allow plugins to dynamically link to symbols such as nbdkit_error exported by nbdkit.exe. An additional complexity is added by libtool which refuses to believe that it's possible to add a *.a file when generating a dynamic library. We must therefore hide the *.a file from libtool by using -Wl options (ie. passing the library directly through to the linker). --- configure.ac | 2 ++ filters/blocksize/Makefile.am | 1 + filters/cache/Makefile.am | 1 + filters/cacheextents/Makefile.am | 1 + filters/cow/Makefile.am | 1 + filters/ddrescue/Makefile.am | 1 + filters/delay/Makefile.am | 3 +++ filters/error/Makefile.am | 1 + filters/exitlast/Makefile.am | 3 +++ filters/ext2/Makefile.am | 3 ++- filters/extentlist/Makefile.am | 1 + filters/fua/Makefile.am | 3 +++ filters/gzip/Makefile.am | 1 + filters/ip/Makefile.am | 1 + filters/limit/Makefile.am | 1 + filters/log/Makefile.am | 1 + filters/nocache/Makefile.am | 3 +++ filters/noextents/Makefile.am | 3 +++ filters/nofilter/Makefile.am | 3 +++ filters/noparallel/Makefile.am | 3 +++ filters/nozero/Makefile.am | 3 +++ filters/offset/Makefile.am | 1 + filters/partition/Makefile.am | 1 + filters/pause/Makefile.am | 1 + filters/rate/Makefile.am | 1 + filters/readahead/Makefile.am | 1 + filters/retry/Makefile.am | 1 + filters/stats/Makefile.am | 1 + filters/swab/Makefile.am | 1 + filters/tar/Makefile.am | 1 + filters/tls-fallback/Makefile.am | 3 +++ filters/truncate/Makefile.am | 1 + filters/xz/Makefile.am | 1 + plugins/cc/Makefile.am | 1 + plugins/cdi/Makefile.am | 1 + plugins/curl/Makefile.am | 3 ++- plugins/data/Makefile.am | 1 + plugins/eval/Makefile.am | 1 + plugins/example1/Makefile.am | 3 +++ plugins/example2/Makefile.am | 3 +++ plugins/example3/Makefile.am | 3 +++ plugins/file/Makefile.am | 1 + plugins/floppy/Makefile.am | 1 + plugins/full/Makefile.am | 3 +++ plugins/guestfs/Makefile.am | 3 ++- plugins/gzip/Makefile.am | 1 + plugins/info/Makefile.am | 1 + plugins/iso/Makefile.am | 1 + plugins/libvirt/Makefile.am | 1 + plugins/linuxdisk/Makefile.am | 1 + plugins/lua/Makefile.am | 3 +++ plugins/memory/Makefile.am | 1 + plugins/nbd/Makefile.am | 1 + plugins/null/Makefile.am | 3 +++ plugins/ondemand/Makefile.am | 1 + plugins/partitioning/Makefile.am | 1 + plugins/pattern/Makefile.am | 3 +++ plugins/perl/Makefile.am | 1 + plugins/python/Makefile.am | 3 ++- plugins/random/Makefile.am | 3 +++ plugins/ruby/Makefile.am | 1 + plugins/sh/Makefile.am | 1 + plugins/split/Makefile.am | 1 + plugins/ssh/Makefile.am | 3 ++- plugins/streaming/Makefile.am | 3 +++ plugins/tar/Makefile.am | 7 ++++--- plugins/tcl/Makefile.am | 1 + plugins/tmpdisk/Makefile.am | 7 ++++--- plugins/torrent/Makefile.am | 11 ++++++----- plugins/vddk/Makefile.am | 1 + plugins/zero/Makefile.am | 3 +++ tests/Makefile.am | 12 ++++++++++++ 72 files changed, 138 insertions(+), 16 deletions(-) diff --git a/configure.ac b/configure.ac index 16762f54..faae1ca7 100644 --- a/configure.ac +++ b/configure.ac @@ -485,11 +485,13 @@ AS_CASE([$host_os], is_windows=yes LIBS="$LIBS -lmsvcrt -lkernel32 -luser32" NO_UNDEFINED_ON_WINDOWS="-no-undefined" + IMPORT_LIBRARY_ON_WINDOWS='-Wl,-L$(top_builddir)/server -Wl,-lnbdkit' ], [is_windows=no] ) AC_MSG_RESULT([$is_windows]) AC_SUBST([NO_UNDEFINED_ON_WINDOWS]) +AC_SUBST([IMPORT_LIBRARY_ON_WINDOWS]) AM_CONDITIONAL([IS_WINDOWS],[test "x$is_windows" = "xyes"]) AS_IF([test "x$is_windows" = "xyes"],[ diff --git a/filters/blocksize/Makefile.am b/filters/blocksize/Makefile.am index ea51246a..5cda19bd 100644 --- a/filters/blocksize/Makefile.am +++ b/filters/blocksize/Makefile.am @@ -52,6 +52,7 @@ nbdkit_blocksize_filter_la_LDFLAGS = \ $(NULL) nbdkit_blocksize_filter_la_LIBADD = \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/filters/cache/Makefile.am b/filters/cache/Makefile.am index 200cda15..e8879807 100644 --- a/filters/cache/Makefile.am +++ b/filters/cache/Makefile.am @@ -61,6 +61,7 @@ nbdkit_cache_filter_la_LDFLAGS = \ nbdkit_cache_filter_la_LIBADD = \ $(top_builddir)/common/bitmap/libbitmap.la \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/filters/cacheextents/Makefile.am b/filters/cacheextents/Makefile.am index 2f7a689b..5ddffe98 100644 --- a/filters/cacheextents/Makefile.am +++ b/filters/cacheextents/Makefile.am @@ -52,6 +52,7 @@ nbdkit_cacheextents_filter_la_LDFLAGS = \ $(NULL) nbdkit_cacheextents_filter_la_LIBADD = \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/filters/cow/Makefile.am b/filters/cow/Makefile.am index 4ff08a44..93ecf76b 100644 --- a/filters/cow/Makefile.am +++ b/filters/cow/Makefile.am @@ -56,6 +56,7 @@ nbdkit_cow_filter_la_LDFLAGS = \ nbdkit_cow_filter_la_LIBADD = \ $(top_builddir)/common/bitmap/libbitmap.la \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/filters/ddrescue/Makefile.am b/filters/ddrescue/Makefile.am index 79bbad9c..e19c022f 100644 --- a/filters/ddrescue/Makefile.am +++ b/filters/ddrescue/Makefile.am @@ -57,6 +57,7 @@ nbdkit_ddrescue_filter_la_LDFLAGS = \ $(NULL) nbdkit_ddrescue_filter_la_LIBADD = \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(GNUTLS_LIBS) \ $(NULL) diff --git a/filters/delay/Makefile.am b/filters/delay/Makefile.am index 470c6062..b77c15ab 100644 --- a/filters/delay/Makefile.am +++ b/filters/delay/Makefile.am @@ -44,6 +44,9 @@ nbdkit_delay_filter_la_CPPFLAGS = \ -I$(top_srcdir)/include \ $(NULL) nbdkit_delay_filter_la_CFLAGS = $(WARNINGS_CFLAGS) +nbdkit_delay_filter_la_LIBADD = \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ + $(NULL) nbdkit_delay_filter_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ -Wl,--version-script=$(top_srcdir)/filters/filters.syms \ diff --git a/filters/error/Makefile.am b/filters/error/Makefile.am index 78e2a7b7..8ce8dc32 100644 --- a/filters/error/Makefile.am +++ b/filters/error/Makefile.am @@ -52,6 +52,7 @@ nbdkit_error_filter_la_LDFLAGS = \ $(NULL) nbdkit_error_filter_la_LIBADD = \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/filters/exitlast/Makefile.am b/filters/exitlast/Makefile.am index 17603951..94f35f7b 100644 --- a/filters/exitlast/Makefile.am +++ b/filters/exitlast/Makefile.am @@ -42,6 +42,9 @@ nbdkit_exitlast_filter_la_SOURCES = \ nbdkit_exitlast_filter_la_CPPFLAGS = -I$(top_srcdir)/include nbdkit_exitlast_filter_la_CFLAGS = $(WARNINGS_CFLAGS) +nbdkit_exitlast_filter_la_LIBADD = \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ + $(NULL) nbdkit_exitlast_filter_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ -Wl,--version-script=$(top_srcdir)/filters/filters.syms \ diff --git a/filters/ext2/Makefile.am b/filters/ext2/Makefile.am index b1fdcb8c..c73f963d 100644 --- a/filters/ext2/Makefile.am +++ b/filters/ext2/Makefile.am @@ -53,8 +53,9 @@ nbdkit_ext2_filter_la_CFLAGS = \ $(EXT2FS_CFLAGS) $(COM_ERR_CFLAGS) \ $(NULL) nbdkit_ext2_filter_la_LIBADD = \ - $(EXT2FS_LIBS) $(COM_ERR_LIBS) \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ + $(EXT2FS_LIBS) $(COM_ERR_LIBS) \ $(NULL) nbdkit_ext2_filter_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ diff --git a/filters/extentlist/Makefile.am b/filters/extentlist/Makefile.am index 612fdfc8..66d3b306 100644 --- a/filters/extentlist/Makefile.am +++ b/filters/extentlist/Makefile.am @@ -52,6 +52,7 @@ nbdkit_extentlist_filter_la_LDFLAGS = \ $(NULL) nbdkit_extentlist_filter_la_LIBADD = \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/filters/fua/Makefile.am b/filters/fua/Makefile.am index 9fd056df..8dfe53f9 100644 --- a/filters/fua/Makefile.am +++ b/filters/fua/Makefile.am @@ -44,6 +44,9 @@ nbdkit_fua_filter_la_CPPFLAGS = \ -I$(top_srcdir)/include \ $(NULL) nbdkit_fua_filter_la_CFLAGS = $(WARNINGS_CFLAGS) +nbdkit_fua_filter_la_LIBADD = \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ + $(NULL) nbdkit_fua_filter_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ -Wl,--version-script=$(top_srcdir)/filters/filters.syms \ diff --git a/filters/gzip/Makefile.am b/filters/gzip/Makefile.am index d122c032..d571b820 100644 --- a/filters/gzip/Makefile.am +++ b/filters/gzip/Makefile.am @@ -53,6 +53,7 @@ nbdkit_gzip_filter_la_CFLAGS = \ $(NULL) nbdkit_gzip_filter_la_LIBADD = \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(ZLIB_LIBS) \ $(NULL) nbdkit_gzip_filter_la_LDFLAGS = \ diff --git a/filters/ip/Makefile.am b/filters/ip/Makefile.am index 16d23057..d09cd1e0 100644 --- a/filters/ip/Makefile.am +++ b/filters/ip/Makefile.am @@ -52,6 +52,7 @@ nbdkit_ip_filter_la_LDFLAGS = \ $(NULL) nbdkit_ip_filter_la_LIBADD = \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/filters/limit/Makefile.am b/filters/limit/Makefile.am index c721700c..b4951ace 100644 --- a/filters/limit/Makefile.am +++ b/filters/limit/Makefile.am @@ -51,6 +51,7 @@ nbdkit_limit_filter_la_LDFLAGS = \ $(NULL) nbdkit_limit_filter_la_LIBADD = \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/filters/log/Makefile.am b/filters/log/Makefile.am index f2c4d813..a31d2a67 100644 --- a/filters/log/Makefile.am +++ b/filters/log/Makefile.am @@ -51,6 +51,7 @@ nbdkit_log_filter_la_LDFLAGS = \ $(NULL) nbdkit_log_filter_la_LIBADD = \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/filters/nocache/Makefile.am b/filters/nocache/Makefile.am index c3cb35f7..aa9fee07 100644 --- a/filters/nocache/Makefile.am +++ b/filters/nocache/Makefile.am @@ -45,6 +45,9 @@ nbdkit_nocache_filter_la_CPPFLAGS = \ -I$(top_srcdir)/common/include \ $(NULL) nbdkit_nocache_filter_la_CFLAGS = $(WARNINGS_CFLAGS) +nbdkit_nocache_filter_la_LIBADD = \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ + $(NULL) nbdkit_nocache_filter_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ -Wl,--version-script=$(top_srcdir)/filters/filters.syms \ diff --git a/filters/noextents/Makefile.am b/filters/noextents/Makefile.am index 81e826e9..c3aa1942 100644 --- a/filters/noextents/Makefile.am +++ b/filters/noextents/Makefile.am @@ -44,6 +44,9 @@ nbdkit_noextents_filter_la_CPPFLAGS = \ -I$(top_srcdir)/include \ $(NULL) nbdkit_noextents_filter_la_CFLAGS = $(WARNINGS_CFLAGS) +nbdkit_noextents_filter_la_LIBADD = \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ + $(NULL) nbdkit_noextents_filter_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ -Wl,--version-script=$(top_srcdir)/filters/filters.syms \ diff --git a/filters/nofilter/Makefile.am b/filters/nofilter/Makefile.am index 77ebe33d..6781fe59 100644 --- a/filters/nofilter/Makefile.am +++ b/filters/nofilter/Makefile.am @@ -45,6 +45,9 @@ nbdkit_nofilter_filter_la_CPPFLAGS = \ -I$(top_srcdir)/common/include \ $(NULL) nbdkit_nofilter_filter_la_CFLAGS = $(WARNINGS_CFLAGS) +nbdkit_nofilter_filter_la_LIBADD = \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ + $(NULL) nbdkit_nofilter_filter_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ -Wl,--version-script=$(top_srcdir)/filters/filters.syms \ diff --git a/filters/noparallel/Makefile.am b/filters/noparallel/Makefile.am index fc5a5522..1630deac 100644 --- a/filters/noparallel/Makefile.am +++ b/filters/noparallel/Makefile.am @@ -45,6 +45,9 @@ nbdkit_noparallel_filter_la_CPPFLAGS = \ -I$(top_srcdir)/common/include \ $(NULL) nbdkit_noparallel_filter_la_CFLAGS = $(WARNINGS_CFLAGS) +nbdkit_noparallel_filter_la_LIBADD = \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ + $(NULL) nbdkit_noparallel_filter_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ -Wl,--version-script=$(top_srcdir)/filters/filters.syms \ diff --git a/filters/nozero/Makefile.am b/filters/nozero/Makefile.am index ab7abf44..628934b2 100644 --- a/filters/nozero/Makefile.am +++ b/filters/nozero/Makefile.am @@ -45,6 +45,9 @@ nbdkit_nozero_filter_la_CPPFLAGS = \ -I$(top_srcdir)/common/include \ $(NULL) nbdkit_nozero_filter_la_CFLAGS = $(WARNINGS_CFLAGS) +nbdkit_nozero_filter_la_LIBADD = \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ + $(NULL) nbdkit_nozero_filter_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ -Wl,--version-script=$(top_srcdir)/filters/filters.syms \ diff --git a/filters/offset/Makefile.am b/filters/offset/Makefile.am index a579b8ce..5437e700 100644 --- a/filters/offset/Makefile.am +++ b/filters/offset/Makefile.am @@ -51,6 +51,7 @@ nbdkit_offset_filter_la_LDFLAGS = \ $(NULL) nbdkit_offset_filter_la_LIBADD = \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/filters/partition/Makefile.am b/filters/partition/Makefile.am index 49e3e213..e8a20c68 100644 --- a/filters/partition/Makefile.am +++ b/filters/partition/Makefile.am @@ -56,6 +56,7 @@ nbdkit_partition_filter_la_LDFLAGS = \ $(NULL) nbdkit_partition_filter_la_LIBADD = \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/filters/pause/Makefile.am b/filters/pause/Makefile.am index 3f83eb03..12600033 100644 --- a/filters/pause/Makefile.am +++ b/filters/pause/Makefile.am @@ -48,6 +48,7 @@ nbdkit_pause_filter_la_CPPFLAGS = \ nbdkit_pause_filter_la_CFLAGS = $(WARNINGS_CFLAGS) nbdkit_pause_filter_la_LIBADD = \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(NULL) nbdkit_pause_filter_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ diff --git a/filters/rate/Makefile.am b/filters/rate/Makefile.am index 7f61ca44..f4cf414a 100644 --- a/filters/rate/Makefile.am +++ b/filters/rate/Makefile.am @@ -50,6 +50,7 @@ nbdkit_rate_filter_la_CPPFLAGS = \ nbdkit_rate_filter_la_CFLAGS = $(WARNINGS_CFLAGS) nbdkit_rate_filter_la_LIBADD = \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(NULL) nbdkit_rate_filter_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ diff --git a/filters/readahead/Makefile.am b/filters/readahead/Makefile.am index 387750c2..3d2c507d 100644 --- a/filters/readahead/Makefile.am +++ b/filters/readahead/Makefile.am @@ -52,6 +52,7 @@ nbdkit_readahead_filter_la_LDFLAGS = \ $(NULL) nbdkit_readahead_filter_la_LIBADD = \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/filters/retry/Makefile.am b/filters/retry/Makefile.am index 1011bff8..14d83cf1 100644 --- a/filters/retry/Makefile.am +++ b/filters/retry/Makefile.am @@ -52,6 +52,7 @@ nbdkit_retry_filter_la_LDFLAGS = \ $(NULL) nbdkit_retry_filter_la_LIBADD = \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/filters/stats/Makefile.am b/filters/stats/Makefile.am index be06a08d..ccfeb3e7 100644 --- a/filters/stats/Makefile.am +++ b/filters/stats/Makefile.am @@ -52,6 +52,7 @@ nbdkit_stats_filter_la_LDFLAGS = \ $(NULL) nbdkit_stats_filter_la_LIBADD = \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/filters/swab/Makefile.am b/filters/swab/Makefile.am index 7acaa6a6..07aefe88 100644 --- a/filters/swab/Makefile.am +++ b/filters/swab/Makefile.am @@ -57,6 +57,7 @@ nbdkit_swab_filter_la_LDFLAGS = \ $(NULL) nbdkit_swab_filter_la_LIBADD = \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(GNUTLS_LIBS) \ $(NULL) diff --git a/filters/tar/Makefile.am b/filters/tar/Makefile.am index 30e973cc..897a5c3b 100644 --- a/filters/tar/Makefile.am +++ b/filters/tar/Makefile.am @@ -52,6 +52,7 @@ nbdkit_tar_filter_la_LDFLAGS = \ $(NULL) nbdkit_tar_filter_la_LIBADD = \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/filters/tls-fallback/Makefile.am b/filters/tls-fallback/Makefile.am index 516c2ccf..530119d9 100644 --- a/filters/tls-fallback/Makefile.am +++ b/filters/tls-fallback/Makefile.am @@ -45,6 +45,9 @@ nbdkit_tls_fallback_filter_la_CPPFLAGS = \ -I$(top_srcdir)/common/include \ $(NULL) nbdkit_tls_fallback_filter_la_CFLAGS = $(WARNINGS_CFLAGS) +nbdkit_tls_fallback_filter_la_LIBADD = \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ + $(NULL) nbdkit_tls_fallback_filter_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ -Wl,--version-script=$(top_srcdir)/filters/filters.syms \ diff --git a/filters/truncate/Makefile.am b/filters/truncate/Makefile.am index 3b3d6aca..3240e46d 100644 --- a/filters/truncate/Makefile.am +++ b/filters/truncate/Makefile.am @@ -52,6 +52,7 @@ nbdkit_truncate_filter_la_LDFLAGS = \ $(NULL) nbdkit_truncate_filter_la_LIBADD = \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/filters/xz/Makefile.am b/filters/xz/Makefile.am index 63bbd1c5..ce6bc342 100644 --- a/filters/xz/Makefile.am +++ b/filters/xz/Makefile.am @@ -57,6 +57,7 @@ nbdkit_xz_filter_la_CFLAGS = \ nbdkit_xz_filter_la_LIBADD = \ $(LIBLZMA_LIBS) \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(NULL) nbdkit_xz_filter_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ diff --git a/plugins/cc/Makefile.am b/plugins/cc/Makefile.am index 82db7200..a624903d 100644 --- a/plugins/cc/Makefile.am +++ b/plugins/cc/Makefile.am @@ -54,6 +54,7 @@ nbdkit_cc_plugin_la_LDFLAGS = \ $(NULL) nbdkit_cc_plugin_la_LIBADD = \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(DL_LIBS) \ $(NULL) diff --git a/plugins/cdi/Makefile.am b/plugins/cdi/Makefile.am index 9ce98d5f..79c669bb 100644 --- a/plugins/cdi/Makefile.am +++ b/plugins/cdi/Makefile.am @@ -55,6 +55,7 @@ nbdkit_cdi_plugin_la_LDFLAGS = \ $(NULL) nbdkit_cdi_plugin_la_LIBADD = \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(JANSSON_LIBS) \ $(NULL) diff --git a/plugins/curl/Makefile.am b/plugins/curl/Makefile.am index 29183f03..d6a57a45 100644 --- a/plugins/curl/Makefile.am +++ b/plugins/curl/Makefile.am @@ -54,8 +54,9 @@ nbdkit_curl_plugin_la_CFLAGS = \ $(CURL_CFLAGS) \ $(NULL) nbdkit_curl_plugin_la_LIBADD = \ - $(CURL_LIBS) \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ + $(CURL_LIBS) \ $(NULL) nbdkit_curl_plugin_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ diff --git a/plugins/data/Makefile.am b/plugins/data/Makefile.am index 01e5eec6..0d219c5e 100644 --- a/plugins/data/Makefile.am +++ b/plugins/data/Makefile.am @@ -64,6 +64,7 @@ nbdkit_data_plugin_la_LIBADD = \ $(top_builddir)/common/allocators/liballocators.la \ $(top_builddir)/common/utils/libutils.la \ $(top_builddir)/common/replacements/libcompat.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(GNUTLS_LIBS) \ $(NULL) diff --git a/plugins/eval/Makefile.am b/plugins/eval/Makefile.am index 4ea8d7d4..762c0b24 100644 --- a/plugins/eval/Makefile.am +++ b/plugins/eval/Makefile.am @@ -65,6 +65,7 @@ nbdkit_eval_plugin_la_CPPFLAGS = \ nbdkit_eval_plugin_la_CFLAGS = $(WARNINGS_CFLAGS) nbdkit_eval_plugin_la_LIBADD = \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(NULL) nbdkit_eval_plugin_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ diff --git a/plugins/example1/Makefile.am b/plugins/example1/Makefile.am index 450b367f..390333df 100644 --- a/plugins/example1/Makefile.am +++ b/plugins/example1/Makefile.am @@ -44,6 +44,9 @@ nbdkit_example1_plugin_la_CPPFLAGS = \ -I$(top_srcdir)/include \ $(NULL) nbdkit_example1_plugin_la_CFLAGS = $(WARNINGS_CFLAGS) +nbdkit_example1_plugin_la_LIBADD = \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ + $(NULL) nbdkit_example1_plugin_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ -Wl,--version-script=$(top_srcdir)/plugins/plugins.syms \ diff --git a/plugins/example2/Makefile.am b/plugins/example2/Makefile.am index 41fe1378..7a392567 100644 --- a/plugins/example2/Makefile.am +++ b/plugins/example2/Makefile.am @@ -44,6 +44,9 @@ nbdkit_example2_plugin_la_CPPFLAGS = \ -I$(top_srcdir)/include \ $(NULL) nbdkit_example2_plugin_la_CFLAGS = $(WARNINGS_CFLAGS) +nbdkit_example2_plugin_la_LIBADD = \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ + $(NULL) nbdkit_example2_plugin_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ -Wl,--version-script=$(top_srcdir)/plugins/plugins.syms \ diff --git a/plugins/example3/Makefile.am b/plugins/example3/Makefile.am index e721896e..092787eb 100644 --- a/plugins/example3/Makefile.am +++ b/plugins/example3/Makefile.am @@ -44,6 +44,9 @@ nbdkit_example3_plugin_la_CPPFLAGS = \ -I$(top_srcdir)/include \ $(NULL) nbdkit_example3_plugin_la_CFLAGS = $(WARNINGS_CFLAGS) +nbdkit_example3_plugin_la_LIBADD = \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ + $(NULL) nbdkit_example3_plugin_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ -Wl,--version-script=$(top_srcdir)/plugins/plugins.syms \ diff --git a/plugins/file/Makefile.am b/plugins/file/Makefile.am index ae72a9c4..a067d0fc 100644 --- a/plugins/file/Makefile.am +++ b/plugins/file/Makefile.am @@ -52,6 +52,7 @@ nbdkit_file_plugin_la_LDFLAGS = \ $(NULL) nbdkit_file_plugin_la_LIBADD = \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/plugins/floppy/Makefile.am b/plugins/floppy/Makefile.am index c788382c..468f93b6 100644 --- a/plugins/floppy/Makefile.am +++ b/plugins/floppy/Makefile.am @@ -61,6 +61,7 @@ nbdkit_floppy_plugin_la_LDFLAGS = \ nbdkit_floppy_plugin_la_LIBADD = \ $(top_builddir)/common/regions/libregions.la \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/plugins/full/Makefile.am b/plugins/full/Makefile.am index 97101d18..e93a4f12 100644 --- a/plugins/full/Makefile.am +++ b/plugins/full/Makefile.am @@ -44,6 +44,9 @@ nbdkit_full_plugin_la_CPPFLAGS = \ -I$(top_srcdir)/include \ $(NULL) nbdkit_full_plugin_la_CFLAGS = $(WARNINGS_CFLAGS) +nbdkit_full_plugin_la_LIBADD = \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ + $(NULL) nbdkit_full_plugin_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ -Wl,--version-script=$(top_srcdir)/plugins/plugins.syms \ diff --git a/plugins/guestfs/Makefile.am b/plugins/guestfs/Makefile.am index ab54daf1..efbffb50 100644 --- a/plugins/guestfs/Makefile.am +++ b/plugins/guestfs/Makefile.am @@ -51,8 +51,9 @@ nbdkit_guestfs_plugin_la_CFLAGS = \ $(LIBGUESTFS_CFLAGS) \ $(NULL) nbdkit_guestfs_plugin_la_LIBADD = \ - $(LIBGUESTFS_LIBS) \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ + $(LIBGUESTFS_LIBS) \ $(NULL) nbdkit_guestfs_plugin_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ diff --git a/plugins/gzip/Makefile.am b/plugins/gzip/Makefile.am index ea8bc480..2c128d57 100644 --- a/plugins/gzip/Makefile.am +++ b/plugins/gzip/Makefile.am @@ -50,6 +50,7 @@ nbdkit_gzip_plugin_la_CFLAGS = \ $(ZLIB_CFLAGS) \ $(NULL) nbdkit_gzip_plugin_la_LIBADD = \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(ZLIB_LIBS) \ $(NULL) nbdkit_gzip_plugin_la_LDFLAGS = \ diff --git a/plugins/info/Makefile.am b/plugins/info/Makefile.am index dc55d93c..e54d727c 100644 --- a/plugins/info/Makefile.am +++ b/plugins/info/Makefile.am @@ -53,6 +53,7 @@ nbdkit_info_plugin_la_LDFLAGS = \ -Wl,--version-script=$(top_srcdir)/plugins/plugins.syms \ $(NULL) nbdkit_info_plugin_la_LIBADD = \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(GNUTLS_LIBS) \ $(NULL) diff --git a/plugins/iso/Makefile.am b/plugins/iso/Makefile.am index 1f1f8416..7c05548e 100644 --- a/plugins/iso/Makefile.am +++ b/plugins/iso/Makefile.am @@ -54,6 +54,7 @@ nbdkit_iso_plugin_la_LDFLAGS = \ $(NULL) nbdkit_iso_plugin_la_LIBADD = \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/plugins/libvirt/Makefile.am b/plugins/libvirt/Makefile.am index e750e544..5b19b2e3 100644 --- a/plugins/libvirt/Makefile.am +++ b/plugins/libvirt/Makefile.am @@ -50,6 +50,7 @@ nbdkit_libvirt_plugin_la_CFLAGS = \ $(LIBVIRT_CFLAGS) \ $(NULL) nbdkit_libvirt_plugin_la_LIBADD = \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(LIBVIRT_LIBS) \ $(NULL) nbdkit_libvirt_plugin_la_LDFLAGS = \ diff --git a/plugins/linuxdisk/Makefile.am b/plugins/linuxdisk/Makefile.am index 7557ee5e..20579bb5 100644 --- a/plugins/linuxdisk/Makefile.am +++ b/plugins/linuxdisk/Makefile.am @@ -58,6 +58,7 @@ nbdkit_linuxdisk_plugin_la_LIBADD = \ $(top_builddir)/common/gpt/libgpt.la \ $(top_builddir)/common/regions/libregions.la \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(NULL) nbdkit_linuxdisk_plugin_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ diff --git a/plugins/lua/Makefile.am b/plugins/lua/Makefile.am index c799de9d..36f6f6d2 100644 --- a/plugins/lua/Makefile.am +++ b/plugins/lua/Makefile.am @@ -52,6 +52,9 @@ nbdkit_lua_plugin_la_CFLAGS = \ $(WARNINGS_CFLAGS) \ $(LUA_CFLAGS) \ $(NULL) +nbdkit_lua_plugin_la_LIBADD = \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ + $(NULL) nbdkit_lua_plugin_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ -Wl,--version-script=$(top_srcdir)/plugins/plugins.syms \ diff --git a/plugins/memory/Makefile.am b/plugins/memory/Makefile.am index 5915baf4..ab0f3a0d 100644 --- a/plugins/memory/Makefile.am +++ b/plugins/memory/Makefile.am @@ -55,6 +55,7 @@ nbdkit_memory_plugin_la_LIBADD = \ $(top_builddir)/common/allocators/liballocators.la \ $(top_builddir)/common/replacements/libcompat.la \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/plugins/nbd/Makefile.am b/plugins/nbd/Makefile.am index 671ae678..1af1fac4 100644 --- a/plugins/nbd/Makefile.am +++ b/plugins/nbd/Makefile.am @@ -58,6 +58,7 @@ nbdkit_nbd_plugin_la_LDFLAGS = \ $(NULL) nbdkit_nbd_plugin_la_LIBADD = \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(LIBNBD_LIBS) \ $(NULL) diff --git a/plugins/null/Makefile.am b/plugins/null/Makefile.am index b07a70a4..9fbe9330 100644 --- a/plugins/null/Makefile.am +++ b/plugins/null/Makefile.am @@ -44,6 +44,9 @@ nbdkit_null_plugin_la_CPPFLAGS = \ -I$(top_srcdir)/include \ $(NULL) nbdkit_null_plugin_la_CFLAGS = $(WARNINGS_CFLAGS) +nbdkit_null_plugin_la_LIBADD = \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ + $(NULL) nbdkit_null_plugin_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ -Wl,--version-script=$(top_srcdir)/plugins/plugins.syms \ diff --git a/plugins/ondemand/Makefile.am b/plugins/ondemand/Makefile.am index 423ac7ae..6312f4b1 100644 --- a/plugins/ondemand/Makefile.am +++ b/plugins/ondemand/Makefile.am @@ -66,6 +66,7 @@ nbdkit_ondemand_plugin_la_LDFLAGS = \ $(NULL) nbdkit_ondemand_plugin_la_LIBADD = \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/plugins/partitioning/Makefile.am b/plugins/partitioning/Makefile.am index 9540d6f6..80f461f3 100644 --- a/plugins/partitioning/Makefile.am +++ b/plugins/partitioning/Makefile.am @@ -63,6 +63,7 @@ nbdkit_partitioning_plugin_la_LIBADD = \ $(top_builddir)/common/regions/libregions.la \ $(top_builddir)/common/utils/libutils.la \ $(top_builddir)/common/replacements/libcompat.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/plugins/pattern/Makefile.am b/plugins/pattern/Makefile.am index dfbbdafa..9935b50a 100644 --- a/plugins/pattern/Makefile.am +++ b/plugins/pattern/Makefile.am @@ -45,6 +45,9 @@ nbdkit_pattern_plugin_la_CPPFLAGS = \ -I$(top_srcdir)/common/include \ $(NULL) nbdkit_pattern_plugin_la_CFLAGS = $(WARNINGS_CFLAGS) +nbdkit_pattern_plugin_la_LIBADD = \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ + $(NULL) nbdkit_pattern_plugin_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ -Wl,--version-script=$(top_srcdir)/plugins/plugins.syms \ diff --git a/plugins/perl/Makefile.am b/plugins/perl/Makefile.am index 858ea258..89fe733e 100644 --- a/plugins/perl/Makefile.am +++ b/plugins/perl/Makefile.am @@ -56,6 +56,7 @@ nbdkit_perl_plugin_la_CFLAGS = \ $(NULL) nbdkit_perl_plugin_la_LIBADD = \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(NULL) nbdkit_perl_plugin_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ diff --git a/plugins/python/Makefile.am b/plugins/python/Makefile.am index b34d0394..e6153d17 100644 --- a/plugins/python/Makefile.am +++ b/plugins/python/Makefile.am @@ -58,8 +58,9 @@ nbdkit_python_plugin_la_CFLAGS = \ $(PYTHON_CFLAGS) \ $(NULL) nbdkit_python_plugin_la_LIBADD = \ - $(PYTHON_LIBS) \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ + $(PYTHON_LIBS) \ $(NULL) nbdkit_python_plugin_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ diff --git a/plugins/random/Makefile.am b/plugins/random/Makefile.am index cb58831f..35443053 100644 --- a/plugins/random/Makefile.am +++ b/plugins/random/Makefile.am @@ -45,6 +45,9 @@ nbdkit_random_plugin_la_CPPFLAGS = \ -I$(top_srcdir)/include \ $(NULL) nbdkit_random_plugin_la_CFLAGS = $(WARNINGS_CFLAGS) +nbdkit_random_plugin_la_LIBADD = \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ + $(NULL) nbdkit_random_plugin_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ -Wl,--version-script=$(top_srcdir)/plugins/plugins.syms \ diff --git a/plugins/ruby/Makefile.am b/plugins/ruby/Makefile.am index c435ff0e..1bd3fad3 100644 --- a/plugins/ruby/Makefile.am +++ b/plugins/ruby/Makefile.am @@ -53,6 +53,7 @@ nbdkit_ruby_plugin_la_CFLAGS = \ $(RUBY_CFLAGS) \ $(NULL) nbdkit_ruby_plugin_la_LIBADD = \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(RUBY_LIBS) \ $(NULL) nbdkit_ruby_plugin_la_LDFLAGS = \ diff --git a/plugins/sh/Makefile.am b/plugins/sh/Makefile.am index 77a3abde..90cf2617 100644 --- a/plugins/sh/Makefile.am +++ b/plugins/sh/Makefile.am @@ -56,6 +56,7 @@ nbdkit_sh_plugin_la_CPPFLAGS = \ nbdkit_sh_plugin_la_CFLAGS = $(WARNINGS_CFLAGS) nbdkit_sh_plugin_la_LIBADD = \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(NULL) nbdkit_sh_plugin_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ diff --git a/plugins/split/Makefile.am b/plugins/split/Makefile.am index 209d669b..7c09d036 100644 --- a/plugins/split/Makefile.am +++ b/plugins/split/Makefile.am @@ -51,6 +51,7 @@ nbdkit_split_plugin_la_LDFLAGS = \ $(NULL) nbdkit_split_plugin_la_LIBADD = \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/plugins/ssh/Makefile.am b/plugins/ssh/Makefile.am index 8b2e9293..4149e8e1 100644 --- a/plugins/ssh/Makefile.am +++ b/plugins/ssh/Makefile.am @@ -52,8 +52,9 @@ nbdkit_ssh_plugin_la_CFLAGS = \ $(SSH_CFLAGS) \ $(NULL) nbdkit_ssh_plugin_la_LIBADD = \ - $(SSH_LIBS) \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ + $(SSH_LIBS) \ $(NULL) nbdkit_ssh_plugin_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ diff --git a/plugins/streaming/Makefile.am b/plugins/streaming/Makefile.am index 7cb7e509..d18d77c7 100644 --- a/plugins/streaming/Makefile.am +++ b/plugins/streaming/Makefile.am @@ -44,6 +44,9 @@ nbdkit_streaming_plugin_la_CPPFLAGS = \ -I$(top_srcdir)/include \ $(NULL) nbdkit_streaming_plugin_la_CFLAGS = $(WARNINGS_CFLAGS) +nbdkit_streaming_plugin_la_LIBADD = \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ + $(NULL) nbdkit_streaming_plugin_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ -Wl,--version-script=$(top_srcdir)/plugins/plugins.syms \ diff --git a/plugins/tar/Makefile.am b/plugins/tar/Makefile.am index 88909189..7ca941c9 100644 --- a/plugins/tar/Makefile.am +++ b/plugins/tar/Makefile.am @@ -46,13 +46,14 @@ nbdkit_tar_plugin_la_CPPFLAGS = \ -I. \ $(NULL) nbdkit_tar_plugin_la_CFLAGS = $(WARNINGS_CFLAGS) +nbdkit_tar_plugin_la_LIBADD = \ + $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ + $(NULL) nbdkit_tar_plugin_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ -Wl,--version-script=$(top_srcdir)/plugins/plugins.syms \ $(NULL) -nbdkit_tar_plugin_la_LIBADD = \ - $(top_builddir)/common/utils/libutils.la \ - $(NULL) if HAVE_POD diff --git a/plugins/tcl/Makefile.am b/plugins/tcl/Makefile.am index 91243dd5..9b5989f0 100644 --- a/plugins/tcl/Makefile.am +++ b/plugins/tcl/Makefile.am @@ -53,6 +53,7 @@ nbdkit_tcl_plugin_la_CFLAGS = \ $(TCL_CFLAGS) \ $(NULL) nbdkit_tcl_plugin_la_LIBADD = \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(TCL_LIBS) \ $(NULL) nbdkit_tcl_plugin_la_LDFLAGS = \ diff --git a/plugins/tmpdisk/Makefile.am b/plugins/tmpdisk/Makefile.am index 69ae85e0..b1e045b1 100644 --- a/plugins/tmpdisk/Makefile.am +++ b/plugins/tmpdisk/Makefile.am @@ -60,13 +60,14 @@ nbdkit_tmpdisk_plugin_la_CPPFLAGS = \ -I$(top_srcdir)/common/utils \ $(NULL) nbdkit_tmpdisk_plugin_la_CFLAGS = $(WARNINGS_CFLAGS) +nbdkit_tmpdisk_plugin_la_LIBADD = \ + $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ + $(NULL) nbdkit_tmpdisk_plugin_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ -Wl,--version-script=$(top_srcdir)/plugins/plugins.syms \ $(NULL) -nbdkit_tmpdisk_plugin_la_LIBADD = \ - $(top_builddir)/common/utils/libutils.la \ - $(NULL) if HAVE_POD diff --git a/plugins/torrent/Makefile.am b/plugins/torrent/Makefile.am index 0097813a..22ca9e9c 100644 --- a/plugins/torrent/Makefile.am +++ b/plugins/torrent/Makefile.am @@ -53,14 +53,15 @@ nbdkit_torrent_plugin_la_CFLAGS = \ $(PTHREAD_CFLAGS) \ $(LIBTORRENT_CFLAGS) \ $(NULL) -nbdkit_torrent_plugin_la_LDFLAGS = \ - -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ - -Wl,--version-script=$(top_srcdir)/plugins/plugins.syms \ - $(NULL) nbdkit_torrent_plugin_la_LIBADD = \ + $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(PTHREAD_LIBS) \ $(LIBTORRENT_LIBS) \ - $(top_builddir)/common/utils/libutils.la \ + $(NULL) +nbdkit_torrent_plugin_la_LDFLAGS = \ + -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ + -Wl,--version-script=$(top_srcdir)/plugins/plugins.syms \ $(NULL) if HAVE_POD diff --git a/plugins/vddk/Makefile.am b/plugins/vddk/Makefile.am index 9902d93c..e334d46d 100644 --- a/plugins/vddk/Makefile.am +++ b/plugins/vddk/Makefile.am @@ -58,6 +58,7 @@ nbdkit_vddk_plugin_la_CPPFLAGS = \ nbdkit_vddk_plugin_la_CFLAGS = $(WARNINGS_CFLAGS) nbdkit_vddk_plugin_la_LIBADD = \ $(top_builddir)/common/utils/libutils.la \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ $(DL_LIBS) \ $(NULL) nbdkit_vddk_plugin_la_LDFLAGS = \ diff --git a/plugins/zero/Makefile.am b/plugins/zero/Makefile.am index 0ec1c396..7b414f4f 100644 --- a/plugins/zero/Makefile.am +++ b/plugins/zero/Makefile.am @@ -43,6 +43,9 @@ nbdkit_zero_plugin_la_SOURCES = \ nbdkit_zero_plugin_la_CPPFLAGS = \ -I$(top_srcdir)/include nbdkit_zero_plugin_la_CFLAGS = $(WARNINGS_CFLAGS) +nbdkit_zero_plugin_la_LIBADD = \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ + $(NULL) nbdkit_zero_plugin_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ -Wl,--version-script=$(top_srcdir)/plugins/plugins.syms \ diff --git a/tests/Makefile.am b/tests/Makefile.am index 2db56ded..516b5a40 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -268,6 +268,9 @@ test_stdio_plugin_la_CFLAGS = $(WARNINGS_CFLAGS) test_stdio_plugin_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) -rpath /nowhere \ $(NULL) +test_stdio_plugin_la_LIBADD = \ + $(IMPORT_LIBRARY_ON_WINDOWS) \ + $(NULL) # check_LTLIBRARIES won't build a shared library (see automake manual). # So we have to do this and add a dependency. @@ -287,6 +290,7 @@ test_flush_plugin_la_CFLAGS = $(WARNINGS_CFLAGS) test_flush_plugin_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) -rpath /nowhere \ $(NULL) +test_flush_plugin_la_LIBADD = $(IMPORT_LIBRARY_ON_WINDOWS) # check_LTLIBRARIES won't build a shared library (see automake manual). # So we have to do this and add a dependency. @@ -306,6 +310,7 @@ test_shutdown_plugin_la_CFLAGS = $(WARNINGS_CFLAGS) test_shutdown_plugin_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) -rpath /nowhere \ $(NULL) +test_shutdown_plugin_la_LIBADD = $(IMPORT_LIBRARY_ON_WINDOWS) endif HAVE_PLUGINS @@ -360,6 +365,7 @@ test_ansi_c_plugin_la_CFLAGS = $(WARNINGS_CFLAGS) test_ansi_c_plugin_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) -rpath /nowhere \ $(NULL) +test_ansi_c_plugin_la_LIBADD = $(IMPORT_LIBRARY_ON_WINDOWS) endif CAN_TEST_ANSI_C if HAVE_CXX @@ -385,6 +391,7 @@ test_cxx_plugin_la_CXXFLAGS = $(WARNINGS_CFLAGS) test_cxx_plugin_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) -rpath /nowhere \ $(NULL) +test_cxx_plugin_la_LIBADD = $(IMPORT_LIBRARY_ON_WINDOWS) test_cxx_filter_la_SOURCES = \ test-cxx-filter.cpp \ @@ -399,6 +406,7 @@ test_cxx_filter_la_CXXFLAGS = $(WARNINGS_CFLAGS) test_cxx_filter_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) -rpath /nowhere \ $(NULL) +test_cxx_filter_la_LIBADD = $(IMPORT_LIBRARY_ON_WINDOWS) endif HAVE_CXX # Exit with parent test. @@ -1227,6 +1235,7 @@ test_layers_plugin_la_CFLAGS = $(WARNINGS_CFLAGS) test_layers_plugin_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) -rpath /nowhere \ $(NULL) +test_layers_plugin_la_LIBADD = $(IMPORT_LIBRARY_ON_WINDOWS) test_layers_filter1_la_SOURCES = \ test-layers-filter.c \ @@ -1239,6 +1248,7 @@ test_layers_filter1_la_CFLAGS = $(WARNINGS_CFLAGS) -Dlayer='"filter1"' test_layers_filter1_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) -rpath /nowhere \ $(NULL) +test_layers_filter1_la_LIBADD = $(IMPORT_LIBRARY_ON_WINDOWS) test_layers_filter2_la_SOURCES = \ test-layers-filter.c \ @@ -1251,6 +1261,7 @@ test_layers_filter2_la_CFLAGS = $(WARNINGS_CFLAGS) -Dlayer='"filter2"' test_layers_filter2_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) -rpath /nowhere \ $(NULL) +test_layers_filter2_la_LIBADD = $(IMPORT_LIBRARY_ON_WINDOWS) test_layers_filter3_la_SOURCES = \ test-layers-filter.c \ @@ -1263,6 +1274,7 @@ test_layers_filter3_la_CFLAGS = $(WARNINGS_CFLAGS) -Dlayer='"filter3"' test_layers_filter3_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) -rpath /nowhere \ $(NULL) +test_layers_filter3_la_LIBADD = $(IMPORT_LIBRARY_ON_WINDOWS) # blocksize filter test. TESTS += test-blocksize.sh test-blocksize-extents.sh -- 2.27.0
--- configure.ac | 1 + plugins/file/Makefile.am | 2 ++ plugins/file/file.c | 23 ++++++++++++++++++----- TODO | 8 +++++--- 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/configure.ac b/configure.ac index faae1ca7..7060f445 100644 --- a/configure.ac +++ b/configure.ac @@ -322,6 +322,7 @@ AC_CHECK_HEADERS([\ stdatomic.h \ syslog.h \ sys/endian.h \ + sys/ioctl.h \ sys/mman.h \ sys/prctl.h \ sys/procctl.h \ diff --git a/plugins/file/Makefile.am b/plugins/file/Makefile.am index a067d0fc..24c443c1 100644 --- a/plugins/file/Makefile.am +++ b/plugins/file/Makefile.am @@ -43,6 +43,7 @@ nbdkit_file_plugin_la_SOURCES = \ nbdkit_file_plugin_la_CPPFLAGS = \ -I$(top_srcdir)/include \ -I$(top_srcdir)/common/include \ + -I$(top_srcdir)/common/replacements \ -I$(top_srcdir)/common/utils \ $(NULL) nbdkit_file_plugin_la_CFLAGS = $(WARNINGS_CFLAGS) @@ -52,6 +53,7 @@ nbdkit_file_plugin_la_LDFLAGS = \ $(NULL) nbdkit_file_plugin_la_LIBADD = \ $(top_builddir)/common/utils/libutils.la \ + $(top_builddir)/common/replacements/libcompat.la \ $(IMPORT_LIBRARY_ON_WINDOWS) \ $(NULL) diff --git a/plugins/file/file.c b/plugins/file/file.c index 08418194..b8c72e77 100644 --- a/plugins/file/file.c +++ b/plugins/file/file.c @@ -39,10 +39,13 @@ #include <inttypes.h> #include <fcntl.h> #include <unistd.h> +#include <errno.h> #include <sys/types.h> #include <sys/stat.h> + +#ifdef HAVE_SYS_IOCTL_H #include <sys/ioctl.h> -#include <errno.h> +#endif #include <pthread.h> @@ -59,10 +62,10 @@ #include "cleanup.h" #include "isaligned.h" - -#ifndef HAVE_FDATASYNC -#define fdatasync fsync -#endif +#include "fdatasync.h" +#include "pread.h" +#include "pwrite.h" +#include "windows-compat.h" static char *filename = NULL; static char *directory = NULL; @@ -116,6 +119,7 @@ file_config (const char *key, const char *value) if (!filename) return -1; } +#ifndef WIN32 else if (strcmp (key, "directory") == 0 || strcmp (key, "dir") == 0) { free (directory); @@ -123,6 +127,7 @@ file_config (const char *key, const char *value) if (!directory) return -1; } +#endif else if (strcmp (key, "fadvise") == 0) { /* As this is a hint, if the kernel doesn't support the feature * ignore the parameter. @@ -263,6 +268,7 @@ file_open (int readonly) int dfd = -1; if (directory) { +#ifndef WIN32 file = nbdkit_export_name (); if (strchr (file, '/')) { nbdkit_error ("exportname cannot contain /"); @@ -274,6 +280,9 @@ file_open (int readonly) nbdkit_error ("open %s: %m", directory); return NULL; } +#else + abort (); +#endif } else file = filename; @@ -290,7 +299,11 @@ file_open (int readonly) else flags |= O_RDWR; +#ifndef WIN32 h->fd = openat (dfd, file, flags); +#else + h->fd = open (file, flags); +#endif if (h->fd == -1) { nbdkit_error ("openat: %s: %m", file); if (dfd != -1) diff --git a/TODO b/TODO index c3314d37..b2b89670 100644 --- a/TODO +++ b/TODO @@ -325,9 +325,11 @@ Currently many features are missing, including: * For possible Unix domain socket support in future see: https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/ -* The file plugin. The current file plugin is essentially POSIX-only. - We would like to eventually write an alternate file plugin which - uses Windows APIs. +* The current file plugin works but has limited features and doesn't + use the best native APIs. It's worth considering writing an + alternate implementation which is used for Windows and uses all + native APIs and features. Also this should be extended to allow + exporting block devices. * Many other plugins and filters. -- 2.27.0
Miscellaneous ports of filters and plugins to Windows. Ones which could not be ported easily are disabled in the Makefile.am with a comment outlining why. --- configure.ac | 2 ++ filters/cache/Makefile.am | 5 +++++ filters/cow/Makefile.am | 2 ++ filters/ddrescue/Makefile.am | 2 ++ filters/extentlist/Makefile.am | 2 ++ filters/gzip/Makefile.am | 2 ++ filters/log/Makefile.am | 4 ++++ filters/pause/Makefile.am | 4 ++++ filters/rate/Makefile.am | 2 ++ filters/tar/Makefile.am | 6 ++++++ plugins/cc/Makefile.am | 5 +++++ plugins/cdi/Makefile.am | 4 ++++ plugins/eval/Makefile.am | 4 ++++ plugins/example2/Makefile.am | 6 ++++++ plugins/example3/Makefile.am | 6 ++++++ plugins/iso/Makefile.am | 7 +++++-- plugins/linuxdisk/Makefile.am | 5 +++-- plugins/ocaml/Makefile.am | 6 ++++-- plugins/ondemand/Makefile.am | 5 +++++ plugins/sh/Makefile.am | 4 ++++ plugins/split/Makefile.am | 2 ++ plugins/streaming/Makefile.am | 5 +++++ plugins/tar/Makefile.am | 3 +++ plugins/tmpdisk/Makefile.am | 4 ++++ plugins/vddk/Makefile.am | 3 +++ plugins/info/info.c | 9 +++++++++ plugins/ondemand/ondemand.c | 3 +++ plugins/partitioning/partitioning.c | 2 ++ plugins/split/split.c | 3 +++ filters/cache/blk.c | 3 +++ filters/cache/cache.c | 5 ++++- filters/cow/blk.c | 10 ++++++---- filters/ddrescue/ddrescue.c | 1 + filters/error/error.c | 1 + filters/extentlist/extentlist.c | 1 + filters/gzip/gzip.c | 1 + filters/ip/ip.c | 9 +++++++++ filters/log/log.c | 1 + filters/nozero/nozero.c | 5 +++++ filters/rate/rate.c | 2 ++ filters/retry/retry.c | 1 + filters/stats/stats.c | 1 + filters/tar/tar.c | 2 +- 43 files changed, 148 insertions(+), 12 deletions(-) diff --git a/configure.ac b/configure.ac index 7060f445..0b17ef95 100644 --- a/configure.ac +++ b/configure.ac @@ -311,6 +311,7 @@ test (void) dnl Check for other headers, all optional. AC_CHECK_HEADERS([\ alloca.h \ + arpa/inet.h \ byteswap.h \ endian.h \ grp.h \ @@ -327,6 +328,7 @@ AC_CHECK_HEADERS([\ sys/prctl.h \ sys/procctl.h \ sys/socket.h \ + sys/statvfs.h \ sys/un.h \ sys/wait.h]) diff --git a/filters/cache/Makefile.am b/filters/cache/Makefile.am index e8879807..2d4e96f4 100644 --- a/filters/cache/Makefile.am +++ b/filters/cache/Makefile.am @@ -33,6 +33,10 @@ include $(top_srcdir)/common-rules.mk EXTRA_DIST = nbdkit-cache-filter.pod +# Requires hole-punching and other OS specific features which make +# this an effort to port to Windows. +if !IS_WINDOWS + filter_LTLIBRARIES = nbdkit-cache-filter.la nbdkit_cache_filter_la_SOURCES = \ @@ -75,3 +79,4 @@ nbdkit-cache-filter.1: nbdkit-cache-filter.pod $< endif HAVE_POD +endif !IS_WINDOWS diff --git a/filters/cow/Makefile.am b/filters/cow/Makefile.am index 93ecf76b..a80ccd8f 100644 --- a/filters/cow/Makefile.am +++ b/filters/cow/Makefile.am @@ -46,6 +46,7 @@ nbdkit_cow_filter_la_CPPFLAGS = \ -I$(top_srcdir)/include \ -I$(top_srcdir)/common/bitmap \ -I$(top_srcdir)/common/include \ + -I$(top_srcdir)/common/replacements \ -I$(top_srcdir)/common/utils \ $(NULL) nbdkit_cow_filter_la_CFLAGS = $(WARNINGS_CFLAGS) @@ -56,6 +57,7 @@ nbdkit_cow_filter_la_LDFLAGS = \ nbdkit_cow_filter_la_LIBADD = \ $(top_builddir)/common/bitmap/libbitmap.la \ $(top_builddir)/common/utils/libutils.la \ + $(top_builddir)/common/replacements/libcompat.la \ $(IMPORT_LIBRARY_ON_WINDOWS) \ $(NULL) diff --git a/filters/ddrescue/Makefile.am b/filters/ddrescue/Makefile.am index e19c022f..68f1937a 100644 --- a/filters/ddrescue/Makefile.am +++ b/filters/ddrescue/Makefile.am @@ -45,6 +45,7 @@ nbdkit_ddrescue_filter_la_SOURCES = \ nbdkit_ddrescue_filter_la_CPPFLAGS = \ -I$(top_srcdir)/include \ -I$(top_srcdir)/common/include \ + -I$(top_srcdir)/common/replacements \ -I$(top_srcdir)/common/utils \ $(NULL) nbdkit_ddrescue_filter_la_CFLAGS = \ @@ -57,6 +58,7 @@ nbdkit_ddrescue_filter_la_LDFLAGS = \ $(NULL) nbdkit_ddrescue_filter_la_LIBADD = \ $(top_builddir)/common/utils/libutils.la \ + $(top_builddir)/common/replacements/libcompat.la \ $(IMPORT_LIBRARY_ON_WINDOWS) \ $(GNUTLS_LIBS) \ $(NULL) diff --git a/filters/extentlist/Makefile.am b/filters/extentlist/Makefile.am index 66d3b306..3965aa76 100644 --- a/filters/extentlist/Makefile.am +++ b/filters/extentlist/Makefile.am @@ -43,6 +43,7 @@ nbdkit_extentlist_filter_la_SOURCES = \ nbdkit_extentlist_filter_la_CPPFLAGS = \ -I$(top_srcdir)/include \ -I$(top_srcdir)/common/include \ + -I$(top_srcdir)/common/replacements \ -I$(top_srcdir)/common/utils \ $(NULL) nbdkit_extentlist_filter_la_CFLAGS = $(WARNINGS_CFLAGS) @@ -52,6 +53,7 @@ nbdkit_extentlist_filter_la_LDFLAGS = \ $(NULL) nbdkit_extentlist_filter_la_LIBADD = \ $(top_builddir)/common/utils/libutils.la \ + $(top_builddir)/common/replacements/libcompat.la \ $(IMPORT_LIBRARY_ON_WINDOWS) \ $(NULL) diff --git a/filters/gzip/Makefile.am b/filters/gzip/Makefile.am index d571b820..428bf036 100644 --- a/filters/gzip/Makefile.am +++ b/filters/gzip/Makefile.am @@ -45,6 +45,7 @@ nbdkit_gzip_filter_la_SOURCES = \ nbdkit_gzip_filter_la_CPPFLAGS = \ -I$(top_srcdir)/include \ -I$(top_srcdir)/common/include \ + -I$(top_srcdir)/common/replacements \ -I$(top_srcdir)/common/utils \ $(NULL) nbdkit_gzip_filter_la_CFLAGS = \ @@ -53,6 +54,7 @@ nbdkit_gzip_filter_la_CFLAGS = \ $(NULL) nbdkit_gzip_filter_la_LIBADD = \ $(top_builddir)/common/utils/libutils.la \ + $(top_builddir)/common/replacements/libcompat.la \ $(IMPORT_LIBRARY_ON_WINDOWS) \ $(ZLIB_LIBS) \ $(NULL) diff --git a/filters/log/Makefile.am b/filters/log/Makefile.am index a31d2a67..a5552664 100644 --- a/filters/log/Makefile.am +++ b/filters/log/Makefile.am @@ -33,6 +33,9 @@ include $(top_srcdir)/common-rules.mk EXTRA_DIST = nbdkit-log-filter.pod +# Requires open_memstream. +if !IS_WINDOWS + filter_LTLIBRARIES = nbdkit-log-filter.la nbdkit_log_filter_la_SOURCES = \ @@ -65,3 +68,4 @@ nbdkit-log-filter.1: nbdkit-log-filter.pod $< endif HAVE_POD +endif !IS_WINDOWS diff --git a/filters/pause/Makefile.am b/filters/pause/Makefile.am index 12600033..108de544 100644 --- a/filters/pause/Makefile.am +++ b/filters/pause/Makefile.am @@ -33,6 +33,9 @@ include $(top_srcdir)/common-rules.mk EXTRA_DIST = nbdkit-pause-filter.pod +# Relies on a Unix domain socket. +if !IS_WINDOWS + filter_LTLIBRARIES = nbdkit-pause-filter.la nbdkit_pause_filter_la_SOURCES = \ @@ -66,3 +69,4 @@ nbdkit-pause-filter.1: nbdkit-pause-filter.pod $< endif HAVE_POD +endif !IS_WINDOWS diff --git a/filters/rate/Makefile.am b/filters/rate/Makefile.am index f4cf414a..ab35dc4a 100644 --- a/filters/rate/Makefile.am +++ b/filters/rate/Makefile.am @@ -45,11 +45,13 @@ nbdkit_rate_filter_la_SOURCES = \ nbdkit_rate_filter_la_CPPFLAGS = \ -I$(top_srcdir)/include \ -I$(top_srcdir)/common/include \ + -I$(top_srcdir)/common/replacements \ -I$(top_srcdir)/common/utils \ $(NULL) nbdkit_rate_filter_la_CFLAGS = $(WARNINGS_CFLAGS) nbdkit_rate_filter_la_LIBADD = \ $(top_builddir)/common/utils/libutils.la \ + $(top_builddir)/common/replacements/libcompat.la \ $(IMPORT_LIBRARY_ON_WINDOWS) \ $(NULL) nbdkit_rate_filter_la_LDFLAGS = \ diff --git a/filters/tar/Makefile.am b/filters/tar/Makefile.am index 897a5c3b..c6b1f750 100644 --- a/filters/tar/Makefile.am +++ b/filters/tar/Makefile.am @@ -33,6 +33,9 @@ include $(top_srcdir)/common-rules.mk EXTRA_DIST = nbdkit-tar-filter.pod +# Requires open_memstream. +if !IS_WINDOWS + filter_LTLIBRARIES = nbdkit-tar-filter.la nbdkit_tar_filter_la_SOURCES = \ @@ -43,6 +46,7 @@ nbdkit_tar_filter_la_SOURCES = \ nbdkit_tar_filter_la_CPPFLAGS = \ -I$(top_srcdir)/include \ -I$(top_srcdir)/common/include \ + -I$(top_srcdir)/common/replacements \ -I$(top_srcdir)/common/utils \ $(NULL) nbdkit_tar_filter_la_CFLAGS = $(WARNINGS_CFLAGS) @@ -52,6 +56,7 @@ nbdkit_tar_filter_la_LDFLAGS = \ $(NULL) nbdkit_tar_filter_la_LIBADD = \ $(top_builddir)/common/utils/libutils.la \ + $(top_builddir)/common/replacements/libcompat.la \ $(IMPORT_LIBRARY_ON_WINDOWS) \ $(NULL) @@ -66,3 +71,4 @@ nbdkit-tar-filter.1: nbdkit-tar-filter.pod $< endif HAVE_POD +endif !IS_WINDOWS diff --git a/plugins/cc/Makefile.am b/plugins/cc/Makefile.am index a624903d..ffee90c5 100644 --- a/plugins/cc/Makefile.am +++ b/plugins/cc/Makefile.am @@ -33,6 +33,10 @@ include $(top_srcdir)/common-rules.mk EXTRA_DIST = nbdkit-cc-plugin.pod +# Disabled on Windows because we lack mkstemps, and possibly cannot +# run shell commands. +if !IS_WINDOWS + plugin_LTLIBRARIES = nbdkit-cc-plugin.la nbdkit_cc_plugin_la_SOURCES = \ @@ -69,3 +73,4 @@ nbdkit-cc-plugin.3: nbdkit-cc-plugin.pod $< endif HAVE_POD +endif !IS_WINDOWS diff --git a/plugins/cdi/Makefile.am b/plugins/cdi/Makefile.am index 79c669bb..be042ba1 100644 --- a/plugins/cdi/Makefile.am +++ b/plugins/cdi/Makefile.am @@ -33,6 +33,9 @@ include $(top_srcdir)/common-rules.mk EXTRA_DIST = nbdkit-cdi-plugin.pod +# Disabled on Windows because this needs to run a bash script. +if !IS_WINDOWS + plugin_LTLIBRARIES = nbdkit-cdi-plugin.la nbdkit_cdi_plugin_la_SOURCES = \ @@ -70,3 +73,4 @@ nbdkit-cdi-plugin.1: nbdkit-cdi-plugin.pod $< endif HAVE_POD +endif !IS_WINDOWS diff --git a/plugins/eval/Makefile.am b/plugins/eval/Makefile.am index 762c0b24..947974e4 100644 --- a/plugins/eval/Makefile.am +++ b/plugins/eval/Makefile.am @@ -33,6 +33,9 @@ include $(top_srcdir)/common-rules.mk EXTRA_DIST = nbdkit-eval-plugin.pod +# Disabled on Windows because no bash scripting. +if !IS_WINDOWS + plugin_LTLIBRARIES = nbdkit-eval-plugin.la # This plugin shares most of the same sources as nbdkit-sh-plugin. In @@ -83,3 +86,4 @@ nbdkit-eval-plugin.1: nbdkit-eval-plugin.pod $< endif HAVE_POD +endif !IS_WINDOWS diff --git a/plugins/example2/Makefile.am b/plugins/example2/Makefile.am index 7a392567..8b0a5412 100644 --- a/plugins/example2/Makefile.am +++ b/plugins/example2/Makefile.am @@ -33,6 +33,11 @@ include $(top_srcdir)/common-rules.mk EXTRA_DIST = nbdkit-example2-plugin.pod +# A Windows port would be quite invasive and detract from the +# educational value of the example. It would be better to have a +# Windows-specific example plugin. +if !IS_WINDOWS + plugin_LTLIBRARIES = nbdkit-example2-plugin.la nbdkit_example2_plugin_la_SOURCES = \ @@ -63,3 +68,4 @@ nbdkit-example2-plugin.1: nbdkit-example2-plugin.pod $< endif HAVE_POD +endif !IS_WINDOWS diff --git a/plugins/example3/Makefile.am b/plugins/example3/Makefile.am index 092787eb..98b47a27 100644 --- a/plugins/example3/Makefile.am +++ b/plugins/example3/Makefile.am @@ -33,6 +33,11 @@ include $(top_srcdir)/common-rules.mk EXTRA_DIST = nbdkit-example3-plugin.pod +# A Windows port would be quite invasive and detract from the +# educational value of the example. It would be better to have a +# Windows-specific example plugin. +if !IS_WINDOWS + plugin_LTLIBRARIES = nbdkit-example3-plugin.la nbdkit_example3_plugin_la_SOURCES = \ @@ -63,3 +68,4 @@ nbdkit-example3-plugin.1: nbdkit-example3-plugin.pod $< endif HAVE_POD +endif !IS_WINDOWS diff --git a/plugins/iso/Makefile.am b/plugins/iso/Makefile.am index 7c05548e..f419feb2 100644 --- a/plugins/iso/Makefile.am +++ b/plugins/iso/Makefile.am @@ -34,6 +34,9 @@ include $(top_srcdir)/common-rules.mk EXTRA_DIST = nbdkit-iso-plugin.pod if HAVE_ISO +# Disabled on Windows because it uses open_memstream to construct the +# command. +if !IS_WINDOWS plugin_LTLIBRARIES = nbdkit-iso-plugin.la @@ -68,5 +71,5 @@ nbdkit-iso-plugin.1: nbdkit-iso-plugin.pod $< endif HAVE_POD - -endif +endif !IS_WINDOWS +endif HAVE_ISO diff --git a/plugins/linuxdisk/Makefile.am b/plugins/linuxdisk/Makefile.am index 20579bb5..d26ee7e9 100644 --- a/plugins/linuxdisk/Makefile.am +++ b/plugins/linuxdisk/Makefile.am @@ -34,6 +34,7 @@ include $(top_srcdir)/common-rules.mk EXTRA_DIST = nbdkit-linuxdisk-plugin.pod if HAVE_MKE2FS_WITH_D +if !IS_WINDOWS plugin_LTLIBRARIES = nbdkit-linuxdisk-plugin.la @@ -76,5 +77,5 @@ nbdkit-linuxdisk-plugin.1: nbdkit-linuxdisk-plugin.pod $< endif HAVE_POD - -endif +endif !IS_WINDOWS +endif HAVE_MKE2FS_WITH_D diff --git a/plugins/ocaml/Makefile.am b/plugins/ocaml/Makefile.am index b9c70bd9..61551d31 100644 --- a/plugins/ocaml/Makefile.am +++ b/plugins/ocaml/Makefile.am @@ -39,6 +39,8 @@ EXTRA_DIST = \ $(NULL) if HAVE_OCAML +# Requires some work to port to Windows. Disable it for now. +if !IS_WINDOWS ocamllibdir = $(OCAMLLIB) ocamllib_DATA = NBDKit.mli NBDKit.cmi NBDKit.cmx NBDKit.o @@ -92,5 +94,5 @@ nbdkit-ocaml-plugin.3: nbdkit-ocaml-plugin.pod $< endif HAVE_POD - -endif +endif !IS_WINDOWS +endif HAVE_OCAML diff --git a/plugins/ondemand/Makefile.am b/plugins/ondemand/Makefile.am index 6312f4b1..7c2f41b9 100644 --- a/plugins/ondemand/Makefile.am +++ b/plugins/ondemand/Makefile.am @@ -36,6 +36,10 @@ EXTRA_DIST = \ nbdkit-ondemand-plugin.pod \ $(NULL) +# Disabled on Windows because it requires open_memstream and other +# porting work. +if !IS_WINDOWS + # The default command we use (if we don't use command=) comes from a # shell script which is turned into a C source file. BUILT_SOURCES = default-command.c @@ -80,3 +84,4 @@ nbdkit-ondemand-plugin.1: nbdkit-ondemand-plugin.pod $< endif HAVE_POD +endif !IS_WINDOWS diff --git a/plugins/sh/Makefile.am b/plugins/sh/Makefile.am index 90cf2617..91bb91cb 100644 --- a/plugins/sh/Makefile.am +++ b/plugins/sh/Makefile.am @@ -37,6 +37,9 @@ EXTRA_DIST = \ example.sh \ $(NULL) +# Disabled on Windows because no bash scripting. +if !IS_WINDOWS + plugin_LTLIBRARIES = nbdkit-sh-plugin.la nbdkit_sh_plugin_la_SOURCES = \ @@ -74,3 +77,4 @@ nbdkit-sh-plugin.3: nbdkit-sh-plugin.pod $< endif HAVE_POD +endif !IS_WINDOWS diff --git a/plugins/split/Makefile.am b/plugins/split/Makefile.am index 7c09d036..1ac0fefe 100644 --- a/plugins/split/Makefile.am +++ b/plugins/split/Makefile.am @@ -42,6 +42,7 @@ nbdkit_split_plugin_la_SOURCES = \ nbdkit_split_plugin_la_CPPFLAGS = \ -I$(top_srcdir)/include \ + -I$(top_srcdir)/common/replacements \ -I$(top_srcdir)/common/utils \ $(NULL) nbdkit_split_plugin_la_CFLAGS = $(WARNINGS_CFLAGS) @@ -51,6 +52,7 @@ nbdkit_split_plugin_la_LDFLAGS = \ $(NULL) nbdkit_split_plugin_la_LIBADD = \ $(top_builddir)/common/utils/libutils.la \ + $(top_builddir)/common/replacements/libcompat.la \ $(IMPORT_LIBRARY_ON_WINDOWS) \ $(NULL) diff --git a/plugins/streaming/Makefile.am b/plugins/streaming/Makefile.am index d18d77c7..5cd92e8e 100644 --- a/plugins/streaming/Makefile.am +++ b/plugins/streaming/Makefile.am @@ -33,6 +33,10 @@ include $(top_srcdir)/common-rules.mk EXTRA_DIST = nbdkit-streaming-plugin.pod +# This will require a special effort to port to Windows because named +# pipes work quite differently. +if !IS_WINDOWS + plugin_LTLIBRARIES = nbdkit-streaming-plugin.la nbdkit_streaming_plugin_la_SOURCES = \ @@ -63,3 +67,4 @@ nbdkit-streaming-plugin.1: nbdkit-streaming-plugin.pod $< endif HAVE_POD +endif !IS_WINDOWS diff --git a/plugins/tar/Makefile.am b/plugins/tar/Makefile.am index 7ca941c9..dbace303 100644 --- a/plugins/tar/Makefile.am +++ b/plugins/tar/Makefile.am @@ -33,6 +33,8 @@ include $(top_srcdir)/common-rules.mk EXTRA_DIST = nbdkit-tar-plugin.pod +if !IS_WINDOWS + plugin_LTLIBRARIES = nbdkit-tar-plugin.la nbdkit_tar_plugin_la_SOURCES = \ @@ -66,3 +68,4 @@ nbdkit-tar-plugin.1: nbdkit-tar-plugin.pod $< endif HAVE_POD +endif !IS_WINDOWS diff --git a/plugins/tmpdisk/Makefile.am b/plugins/tmpdisk/Makefile.am index b1e045b1..ae263e1f 100644 --- a/plugins/tmpdisk/Makefile.am +++ b/plugins/tmpdisk/Makefile.am @@ -36,6 +36,9 @@ EXTRA_DIST = \ nbdkit-tmpdisk-plugin.pod \ $(NULL) +# Requires running a bash script. +if !IS_WINDOWS + # The default command we use (if we don't use command=) comes from a # shell script which is turned into a C source file. BUILT_SOURCES = default-command.c @@ -80,3 +83,4 @@ nbdkit-tmpdisk-plugin.1: nbdkit-tmpdisk-plugin.pod $< endif HAVE_POD +endif !IS_WINDOWS diff --git a/plugins/vddk/Makefile.am b/plugins/vddk/Makefile.am index e334d46d..232aaedd 100644 --- a/plugins/vddk/Makefile.am +++ b/plugins/vddk/Makefile.am @@ -37,6 +37,8 @@ EXTRA_DIST = \ $(NULL) if HAVE_VDDK +# Windows VDDK likely works in a completely different way. +if !IS_WINDOWS plugin_LTLIBRARIES = nbdkit-vddk-plugin.la @@ -78,4 +80,5 @@ nbdkit-vddk-plugin.1: nbdkit-vddk-plugin.pod endif HAVE_POD +endif !IS_WINDOWS endif HAVE_VDDK diff --git a/plugins/info/info.c b/plugins/info/info.c index 33c4facd..0486d60f 100644 --- a/plugins/info/info.c +++ b/plugins/info/info.c @@ -36,9 +36,18 @@ #include <stdlib.h> #include <string.h> #include <sys/time.h> + +#ifdef HAVE_SYS_SOCKET_H #include <sys/socket.h> +#endif + +#ifdef HAVE_NETINET_IN_H #include <netinet/in.h> +#endif + +#ifdef HAVE_ARPA_INET_H #include <arpa/inet.h> +#endif #if defined(HAVE_GNUTLS) && defined(HAVE_GNUTLS_BASE64_DECODE2) #include <gnutls/gnutls.h> diff --git a/plugins/ondemand/ondemand.c b/plugins/ondemand/ondemand.c index 6bdf5c32..2386e1a6 100644 --- a/plugins/ondemand/ondemand.c +++ b/plugins/ondemand/ondemand.c @@ -45,7 +45,10 @@ #include <assert.h> #include <sys/types.h> #include <sys/stat.h> + +#ifdef HAVE_SYS_WAIT_H #include <sys/wait.h> +#endif #include <pthread.h> diff --git a/plugins/partitioning/partitioning.c b/plugins/partitioning/partitioning.c index 79b56dd6..fe34c758 100644 --- a/plugins/partitioning/partitioning.c +++ b/plugins/partitioning/partitioning.c @@ -53,6 +53,8 @@ #include "fdatasync.h" #include "isaligned.h" #include "iszero.h" +#include "pread.h" +#include "pwrite.h" #include "rounding.h" #include "vector.h" diff --git a/plugins/split/split.c b/plugins/split/split.c index a12b1037..3380a6e0 100644 --- a/plugins/split/split.c +++ b/plugins/split/split.c @@ -47,6 +47,9 @@ #include <nbdkit-plugin.h> #include "cleanup.h" +#include "pread.h" +#include "pwrite.h" +#include "windows-compat.h" #include "vector.h" /* The files. */ diff --git a/filters/cache/blk.c b/filters/cache/blk.c index 60c12caf..dc1bcc57 100644 --- a/filters/cache/blk.c +++ b/filters/cache/blk.c @@ -45,7 +45,10 @@ #include <unistd.h> #include <fcntl.h> #include <errno.h> + +#ifdef HAVE_SYS_STATVFS_H #include <sys/statvfs.h> +#endif #include <nbdkit-filter.h> diff --git a/filters/cache/cache.c b/filters/cache/cache.c index db32619d..91dcc43d 100644 --- a/filters/cache/cache.c +++ b/filters/cache/cache.c @@ -41,9 +41,12 @@ #include <unistd.h> #include <fcntl.h> #include <errno.h> +#include <assert.h> #include <sys/types.h> + +#ifdef HAVE_SYS_IOCTL_H #include <sys/ioctl.h> -#include <assert.h> +#endif #include <pthread.h> diff --git a/filters/cow/blk.c b/filters/cow/blk.c index 7fd7bc37..10af4a84 100644 --- a/filters/cow/blk.c +++ b/filters/cow/blk.c @@ -71,7 +71,10 @@ #include <fcntl.h> #include <errno.h> #include <sys/types.h> + +#ifdef HAVE_SYS_IOCTL_H #include <sys/ioctl.h> +#endif #ifdef HAVE_ALLOCA_H #include <alloca.h> @@ -80,14 +83,13 @@ #include <nbdkit-filter.h> #include "bitmap.h" +#include "fdatasync.h" +#include "pread.h" +#include "pwrite.h" #include "utils.h" #include "blk.h" -#ifndef HAVE_FDATASYNC -#define fdatasync fsync -#endif - /* The temporary overlay. */ static int fd = -1; diff --git a/filters/ddrescue/ddrescue.c b/filters/ddrescue/ddrescue.c index a60f07e6..53a03f8d 100644 --- a/filters/ddrescue/ddrescue.c +++ b/filters/ddrescue/ddrescue.c @@ -43,6 +43,7 @@ #include <nbdkit-filter.h> #include "cleanup.h" +#include "getline.h" #include "vector.h" struct range { diff --git a/filters/error/error.c b/filters/error/error.c index 45e434d4..a7ed3f3b 100644 --- a/filters/error/error.c +++ b/filters/error/error.c @@ -47,6 +47,7 @@ #include "cleanup.h" #include "random.h" +#include "windows-compat.h" struct error_settings { int error; /* errno, eg. EIO */ diff --git a/filters/extentlist/extentlist.c b/filters/extentlist/extentlist.c index dfb5e808..98b65f9e 100644 --- a/filters/extentlist/extentlist.c +++ b/filters/extentlist/extentlist.c @@ -43,6 +43,7 @@ #include <nbdkit-filter.h> #include "cleanup.h" +#include "getline.h" #include "minmax.h" #include "vector.h" diff --git a/filters/gzip/gzip.c b/filters/gzip/gzip.c index d92e00d9..929260bf 100644 --- a/filters/gzip/gzip.c +++ b/filters/gzip/gzip.c @@ -46,6 +46,7 @@ #include <nbdkit-filter.h> #include "cleanup.h" +#include "pread.h" #include "minmax.h" /* The first thread to call gzip_prepare has to uncompress the whole diff --git a/filters/ip/ip.c b/filters/ip/ip.c index 26a34d6e..6e64042d 100644 --- a/filters/ip/ip.c +++ b/filters/ip/ip.c @@ -39,9 +39,18 @@ #include <inttypes.h> #include <string.h> #include <assert.h> + +#ifdef HAVE_SYS_SOCKET_H #include <sys/socket.h> +#endif + +#ifdef HAVE_ARPA_INET_H #include <arpa/inet.h> +#endif + +#ifdef HAVE_NETINET_IN_H #include <netinet/in.h> +#endif #include <nbdkit-filter.h> diff --git a/filters/log/log.c b/filters/log/log.c index 71c21211..1ba6486f 100644 --- a/filters/log/log.c +++ b/filters/log/log.c @@ -49,6 +49,7 @@ #include "cleanup.h" #include "utils.h" +#include "windows-compat.h" static uint64_t connections; static char *logfilename; diff --git a/filters/nozero/nozero.c b/filters/nozero/nozero.c index d14b248c..22d5914c 100644 --- a/filters/nozero/nozero.c +++ b/filters/nozero/nozero.c @@ -44,6 +44,11 @@ #include "minmax.h" +/* IGNORE is defined as a macro in Windows headers files ... */ +#ifdef IGNORE +#undef IGNORE +#endif + #define MAX_WRITE (64 * 1024 * 1024) static enum ZeroMode { diff --git a/filters/rate/rate.c b/filters/rate/rate.c index 325f5657..103eae0b 100644 --- a/filters/rate/rate.c +++ b/filters/rate/rate.c @@ -49,6 +49,8 @@ #include <nbdkit-filter.h> #include "cleanup.h" +#include "getline.h" +#include "windows-compat.h" #include "bucket.h" diff --git a/filters/retry/retry.c b/filters/retry/retry.c index a2e57d77..472cf96b 100644 --- a/filters/retry/retry.c +++ b/filters/retry/retry.c @@ -43,6 +43,7 @@ #include <nbdkit-filter.h> #include "cleanup.h" +#include "windows-compat.h" static unsigned retries = 5; /* 0 = filter is disabled */ static unsigned initial_delay = 2; diff --git a/filters/stats/stats.c b/filters/stats/stats.c index 687dd05b..639ceacf 100644 --- a/filters/stats/stats.c +++ b/filters/stats/stats.c @@ -48,6 +48,7 @@ #include "cleanup.h" #include "tvdiff.h" +#include "windows-compat.h" static char *filename; static bool append; diff --git a/filters/tar/tar.c b/filters/tar/tar.c index ab041153..cb42b918 100644 --- a/filters/tar/tar.c +++ b/filters/tar/tar.c @@ -39,7 +39,6 @@ #include <inttypes.h> #include <string.h> #include <unistd.h> -#include <poll.h> #include <assert.h> #include <sys/types.h> #include <sys/stat.h> @@ -49,6 +48,7 @@ #include <nbdkit-filter.h> #include "cleanup.h" +#include "poll.h" #include "minmax.h" #include "utils.h" -- 2.27.0
This also defines SOEXT as the extension of shared objects (ie. "so" or "dll"), and uses it everywhere. I assumed this must already be defined by either autoconf or mingw (like OBJEXT) but I cannot find anything except in glib (G_MODULE_SUFFIX). Thanks: Zebediah Figura for helping out with exec vs spawn on Windows. --- configure.ac | 8 +++- common/utils/windows-compat.h | 3 ++ server/fuzzer.c | 2 +- server/main.c | 6 +-- wrapper.c | 72 ++++++++++++++++++++++++++++++++--- README | 18 ++++----- 6 files changed, 87 insertions(+), 22 deletions(-) diff --git a/configure.ac b/configure.ac index 0b17ef95..61ee3a02 100644 --- a/configure.ac +++ b/configure.ac @@ -489,12 +489,18 @@ AS_CASE([$host_os], LIBS="$LIBS -lmsvcrt -lkernel32 -luser32" NO_UNDEFINED_ON_WINDOWS="-no-undefined" IMPORT_LIBRARY_ON_WINDOWS='-Wl,-L$(top_builddir)/server -Wl,-lnbdkit' + SOEXT="dll" ], - [is_windows=no] + [is_windows=no], [ + SOEXT="so" + ] ) AC_MSG_RESULT([$is_windows]) AC_SUBST([NO_UNDEFINED_ON_WINDOWS]) AC_SUBST([IMPORT_LIBRARY_ON_WINDOWS]) +AC_SUBST([SOEXT]) +AC_DEFINE_UNQUOTED([SOEXT],["$SOEXT"],[Extension used for shared objects/DLLs.]) +AC_DEFINE_UNQUOTED([EXEEXT],["$EXEEXT"],[Extension used for executables.]) AM_CONDITIONAL([IS_WINDOWS],[test "x$is_windows" = "xyes"]) AS_IF([test "x$is_windows" = "xyes"],[ diff --git a/common/utils/windows-compat.h b/common/utils/windows-compat.h index 74241a19..0fcb20d2 100644 --- a/common/utils/windows-compat.h +++ b/common/utils/windows-compat.h @@ -103,6 +103,9 @@ extern int win_send (int fd, const void *buf, size_t len, int flags); #define dup _dup #define dup2 _dup2 +/* setenv replacement. */ +#define setenv(k, v, replace) _putenv_s ((k), (v)); + /* Unfortunately quite commonly used at the moment. Make it a common * macro so we can easily find places which need porting. * diff --git a/server/fuzzer.c b/server/fuzzer.c index c28a1798..4bbb0061 100644 --- a/server/fuzzer.c +++ b/server/fuzzer.c @@ -119,7 +119,7 @@ server (int sock) "nbdkit", "-s", /* take input from stdin/stdout */ "--log=null", /* discard error messages */ - "plugins/memory/.libs/nbdkit-memory-plugin.so", "1M", + "plugins/memory/.libs/nbdkit-memory-plugin." SOEXT, "1M", NULL }; const int argc = sizeof argv / sizeof argv[0] - 1; diff --git a/server/main.c b/server/main.c index fa5073d6..4b6f72e1 100644 --- a/server/main.c +++ b/server/main.c @@ -497,7 +497,7 @@ main (int argc, char *argv[]) /* Incorrect use of --dump-plugin. */ fprintf (stderr, "%s: use 'nbdkit plugin --dump-plugin' or\n" - "'nbdkit /path/to/plugin.so --dump-plugin'\n", + "'nbdkit /path/to/plugin." SOEXT " --dump-plugin'\n", program_name); exit (EXIT_FAILURE); } @@ -819,7 +819,7 @@ open_plugin_so (size_t i, const char *name, int short_name) if (short_name) { /* Short names are rewritten relative to the plugindir. */ if (asprintf (&filename, - "%s/nbdkit-%s-plugin.so", plugindir, name) == -1) { + "%s/nbdkit-%s-plugin." SOEXT, plugindir, name) == -1) { perror ("asprintf"); exit (EXIT_FAILURE); } @@ -872,7 +872,7 @@ open_filter_so (struct backend *next, size_t i, if (short_name) { /* Short names are rewritten relative to the filterdir. */ if (asprintf (&filename, - "%s/nbdkit-%s-filter.so", filterdir, name) == -1) { + "%s/nbdkit-%s-filter." SOEXT, filterdir, name) == -1) { perror ("asprintf"); exit (EXIT_FAILURE); } diff --git a/wrapper.c b/wrapper.c index c27afae0..fe750936 100644 --- a/wrapper.c +++ b/wrapper.c @@ -72,6 +72,7 @@ #include <time.h> #include "options.h" +#include "windows-compat.h" #include "utils.h" /* Construct an array of parameters passed through to real nbdkit. */ @@ -131,6 +132,45 @@ print_command (void) fputc ('\n', stderr); } +#ifdef WIN32 +/* Windows behaviour of _spawnvp is completely retarded: + * https://stackoverflow.com/questions/4146980/how-to-avoid-space-splitting-and... + */ +static const char * +quote_string_for_spawn (const char *str) +{ + size_t i, len; + char *p, *ret = (char *) str; + + if (strchr (str, ' ') || strchr (str, '"')) { + len = strlen (str); + + p = ret = malloc (2 + len*2 + 1); + if (ret == NULL) { + perror ("malloc"); + exit (EXIT_FAILURE); + } + + *p++ = '"'; + for (i = 0; i < len; ++i) { + switch (str[i]) { + case '"': + *p++ = '\\'; + *p++ = '"'; + break; + default: + *p++ = str[i]; + } + } + *p++ = '"'; + *p++ = '\0'; + } + + /* We never free these strings. */ + return ret; +} +#endif /* WIN32 */ + int main (int argc, char *argv[]) { @@ -141,6 +181,7 @@ main (int argc, char *argv[]) char ts[32]; int r; +#ifndef WIN32 /* If NBDKIT_VALGRIND=1 is set in the environment, then we run the * program under valgrind. This is used by the tests. Similarly if * NBDKIT_GDB=1 is set, we run the program under GDB, useful during @@ -167,9 +208,15 @@ main (int argc, char *argv[]) passthru ("--args"); } } +#endif /* Needed for plugins written in OCaml. */ - s = getenv ("LD_LIBRARY_PATH"); +#ifndef WIN32 +#define LD_LIBRARY_PATH "LD_LIBRARY_PATH" +#else +#define LD_LIBRARY_PATH "PATH" +#endif + s = getenv (LD_LIBRARY_PATH); if (s) r = asprintf (&s, "%s/plugins/ocaml/.libs:%s", builddir, s); else @@ -178,7 +225,7 @@ main (int argc, char *argv[]) perror ("asprintf"); exit (EXIT_FAILURE); } - setenv ("LD_LIBRARY_PATH", s, 1); + setenv (LD_LIBRARY_PATH, s, 1); free (s); s = getenv ("LIBRARY_PATH"); if (s) @@ -193,7 +240,7 @@ main (int argc, char *argv[]) free (s); /* Absolute path of the real nbdkit command. */ - passthru_format ("%s/server/nbdkit", builddir); + passthru_format ("%s/server/nbdkit" EXEEXT, builddir); /* Option parsing. We don't really parse options here. We are only * interested in which options have arguments and which need @@ -225,7 +272,8 @@ main (int argc, char *argv[]) /* Filters can be rewritten if they are a short name. */ else if (c == FILTER_OPTION) { if (is_short_name (optarg)) - passthru_format ("--filter=%s/filters/%s/.libs/nbdkit-%s-filter.so", + passthru_format ("--filter=" + "%s/filters/%s/.libs/nbdkit-%s-filter." SOEXT, builddir, optarg, optarg); else passthru_format ("--filter=%s", optarg); @@ -258,13 +306,13 @@ main (int argc, char *argv[]) if (is_short_name (argv[optind])) { /* Special plugins written in Perl. */ if (is_perl_plugin (argv[optind])) { - passthru_format ("%s/plugins/perl/.libs/nbdkit-perl-plugin.so", + passthru_format ("%s/plugins/perl/.libs/nbdkit-perl-plugin." SOEXT, builddir); passthru_format ("%s/plugins/%s/nbdkit-%s-plugin", builddir, argv[optind], argv[optind]); } else { - passthru_format ("%s/plugins/%s/.libs/nbdkit-%s-plugin.so", + passthru_format ("%s/plugins/%s/.libs/nbdkit-%s-plugin." SOEXT, builddir, argv[optind], argv[optind]); } ++optind; @@ -295,7 +343,19 @@ main (int argc, char *argv[]) setenv ("MALLOC_PERTURB_", ts, 0); /* Run the final command. */ +#ifndef WIN32 execvp (cmd[0], (char **) cmd); perror (cmd[0]); exit (EXIT_FAILURE); +#else /* WIN32 */ + size_t i; + for (i = 1; cmd[i] != NULL; ++i) + cmd[i] = quote_string_for_spawn (cmd[i]); + r = _spawnvp (_P_WAIT, cmd[0], cmd); + if (r == -1) { + perror (cmd[0]); + exit (EXIT_FAILURE); + } + exit (r == 0 ? EXIT_SUCCESS : EXIT_FAILURE); +#endif /* WIN32 */ } diff --git a/README b/README index 2bf8ce5f..56b0c984 100644 --- a/README +++ b/README @@ -331,21 +331,17 @@ To cross compile do: mingw64-configure --disable-ocaml --disable-perl --disable-vddk mingw64-make -It is expected to fail, but check that it gets as far as building -server/nbdkit.exe. You can test if the server is working by doing: +You can test if the server is working by doing: - wine server/nbdkit.exe --dump-config + ./nbdkit.exe --dump-config -Now try to build plugins and filters (many will not compile): +(This usually runs wine automatically. If not, you may need to prefix +the command "wine ./nbdkit.exe ...") - mingw64-make -k +To see which plugins and filters were compiled: -To see which ones were compiled: - - find -name '*.dll' + find plugins filters -name '*.dll' You can run them under Wine without installing using eg: - wine server/nbdkit.exe -f -v \ - plugins/memory/.libs/nbdkit-memory-plugin.dll \ - size=1G + ./nbdkit.exe -f -v memory 1G -- 2.27.0
On Thu, Aug 20, 2020 at 12:37:45PM +0100, Richard W.M. Jones wrote:
diff --git a/configure.ac b/configure.ac index 0b17ef95..61ee3a02 100644 --- a/configure.ac +++ b/configure.ac @@ -489,12 +489,18 @@ AS_CASE([$host_os], LIBS="$LIBS -lmsvcrt -lkernel32 -luser32" NO_UNDEFINED_ON_WINDOWS="-no-undefined" IMPORT_LIBRARY_ON_WINDOWS='-Wl,-L$(top_builddir)/server -Wl,-lnbdkit' + SOEXT="dll" ], - [is_windows=no] + [is_windows=no], [ + SOEXT="so" + ]
This is wrong for the non-Windows case. It should be:
+ [is_windows=no + SOEXT="so"]
Fixed in my copy. 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
The vast majority of tests fail currently because Unix domain sockets have not been implemented. There is some hope we could make them work, see: https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/ --- server/Makefile.am | 10 +++++++- tests/Makefile.am | 47 +++++++++++++++++++++++++++------- server/test-public.c | 11 ++++++++ common/utils/test-quotes.c | 14 ++++++++++ tests/test-ansi-c.sh | 2 +- tests/test-binary.sh | 3 ++- tests/test-cxx.sh | 3 ++- tests/test-flush.sh | 2 +- tests/test-layers.sh | 2 +- tests/test-shutdown.sh | 2 +- tests/test-stdio.sh | 2 +- tests/functions.sh.in | 4 ++- tests/test-exit-with-parent.c | 5 +++- tests/test-layers.c | 29 ++++++++++++++++++--- tests/test-socket-activation.c | 9 +++++++ tests/test-stdio-plugin.c | 2 ++ tests/test.c | 26 +++++++++++++++++-- .gitignore | 1 + 18 files changed, 149 insertions(+), 25 deletions(-) diff --git a/server/Makefile.am b/server/Makefile.am index 11b3042e..984e8133 100644 --- a/server/Makefile.am +++ b/server/Makefile.am @@ -174,7 +174,15 @@ test_public_CPPFLAGS = \ -I$(top_srcdir)/common/replacements \ -I$(top_srcdir)/common/utils \ $(NULL) -test_public_CFLAGS = $(WARNINGS_CFLAGS) $(VALGRIND_CFLAGS) +test_public_CFLAGS = \ + $(PTHREAD_CFLAGS) \ + $(WARNINGS_CFLAGS) \ + $(VALGRIND_CFLAGS) \ + $(NULL) +test_public_LDFLAGS = \ + $(PTHREAD_LIBS) \ + $(NULL) test_public_LDADD = \ $(top_builddir)/common/utils/libutils.la \ + $(top_builddir)/common/replacements/libcompat.la \ $(NULL) diff --git a/tests/Makefile.am b/tests/Makefile.am index 516b5a40..bac867e7 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -60,14 +60,9 @@ noinst_LTLIBRARIES = EXTRA_DIST = README.tests EXTRA_PROGRAMS = -# Ensure we're testing the local copy by running everything through -# the nbdkit helper script in the top build directory. -# # Use the 'direct' backend, and ensure maximum libguestfs debugging. -# # Enable libnbd debugging. TESTS_ENVIRONMENT = \ - PATH=$(abs_top_builddir):$(PATH) \ SRCDIR=$(srcdir) \ LIBGUESTFS_ATTACH_METHOD=appliance \ LIBGUESTFS_DEBUG=1 \ @@ -75,10 +70,30 @@ TESTS_ENVIRONMENT = \ LIBNBD_DEBUG=1 \ $(NULL) +if !IS_WINDOWS +# Ensure we're testing the local copy by running everything through +# the nbdkit helper script in the top build directory. +TESTS_ENVIRONMENT += PATH=$(abs_top_builddir):$(PATH) +else +# Since most tests refer to "nbdkit" but on Windows the wrapper is +# called "nbdkit.exe", we must make a "wrapper wrapper" called +# "nbdkit" in some other directory, and the tests/ directory is +# convenient. For some reason a symlink doesn't work here. +noinst_SCRIPTS = nbdkit +nbdkit: Makefile + rm -f $@ + echo 'exec $(abs_top_builddir)/nbdkit.exe "$$@"' > $@ + chmod 0555 $@ +CLEANFILES += nbdkit +TESTS_ENVIRONMENT += PATH=$(abs_builddir):$(PATH) +endif + # Common disk image shared with several tests. These are built # conditionally, so tests should check the files they need exist and # skip if not present. +if !IS_WINDOWS if HAVE_MKE2FS_WITH_D + check_DATA += disk disk.tar CLEANFILES += disk disk.tar @@ -119,7 +134,8 @@ disk.tar.xz: disk.tar xz --best --block-size=32768 --keep $< endif HAVE_LIBLZMA -endif +endif HAVE_MKE2FS_WITH_D +endif !IS_WINDOWS #---------------------------------------------------------------------- # Use 'make check' to run the ordinary tests as non-root. The @@ -190,7 +206,6 @@ TESTS += \ test-tls-psk.sh \ test-ip.sh \ test-vsock.sh \ - test-socket-activation \ test-foreground.sh \ test-debug-flags.sh \ test-long-name.sh \ @@ -229,16 +244,21 @@ EXTRA_DIST += \ test-single-sh.sh \ test-single.sh \ test-start.sh \ - test-stdio.sh \ test-swap.sh \ test-tls-psk.sh \ test-tls.sh \ test-version-example1.sh \ test-version-filter.sh \ test-version-plugin.sh \ + $(NULL) +if !IS_WINDOWS +TESTS += \ test-vsock.sh \ $(NULL) +endif +if !IS_WINDOWS +TESTS += test-socket-activation check_PROGRAMS += \ test-socket-activation \ $(NULL) @@ -249,7 +269,10 @@ test_socket_activation_CPPFLAGS = \ -I$(top_srcdir)/common/protocol \ $(NULL) test_socket_activation_CFLAGS = $(WARNINGS_CFLAGS) +endif +if !IS_WINDOWS +TESTS += test-stdio.sh # check_LTLIBRARIES won't build a shared library (see automake manual). # So we have to do this and add a dependency. noinst_LTLIBRARIES += \ @@ -261,7 +284,10 @@ test_stdio_plugin_la_SOURCES = \ test-stdio-plugin.c \ $(top_srcdir)/include/nbdkit-plugin.h \ $(NULL) -test_stdio_plugin_la_CPPFLAGS = -I$(top_srcdir)/include +test_stdio_plugin_la_CPPFLAGS = \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/common/replacements \ + $(NULL) test_stdio_plugin_la_CFLAGS = $(WARNINGS_CFLAGS) # For use of the -rpath option, see: # https://lists.gnu.org/archive/html/libtool/2007-07/msg00067.html @@ -269,8 +295,11 @@ test_stdio_plugin_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) -rpath /nowhere \ $(NULL) test_stdio_plugin_la_LIBADD = \ + $(top_builddir)/common/replacements/libcompat.la \ + $(top_builddir)/common/utils/libutils.la \ $(IMPORT_LIBRARY_ON_WINDOWS) \ $(NULL) +endif # check_LTLIBRARIES won't build a shared library (see automake manual). # So we have to do this and add a dependency. diff --git a/server/test-public.c b/server/test-public.c index 8ea2ee00..f14e7841 100644 --- a/server/test-public.c +++ b/server/test-public.c @@ -41,6 +41,8 @@ #include <string.h> #include <unistd.h> +#include <pthread.h> + #include "internal.h" static bool error_flagged; @@ -53,11 +55,20 @@ nbdkit_error (const char *fs, ...) error_flagged = true; } +void +nbdkit_debug (const char *fs, ...) +{ +} + bool listen_stdin; bool configured; volatile int quit; +#ifndef WIN32 int quit_fd = -1; +#else +extern HANDLE quit_fd; +#endif struct connection * threadlocal_get_conn (void) diff --git a/common/utils/test-quotes.c b/common/utils/test-quotes.c index dbd17d2e..bb825788 100644 --- a/common/utils/test-quotes.c +++ b/common/utils/test-quotes.c @@ -43,6 +43,8 @@ #include "utils.h" +#ifdef HAVE_OPEN_MEMSTREAM + static bool test (const char *orig, const char *fnname, void (*fn) (const char *, FILE *), const char *exp) @@ -97,3 +99,15 @@ main (void) } return fail ? EXIT_FAILURE : EXIT_SUCCESS; } + +#else /* !OPEN_MEMSTREAM */ + +int +main (int argc, char *argv[]) +{ + fprintf (stderr, "%s: test skipped because no support for open_memstream\n", + argv[0]); + exit (77); +} + +#endif /* !OPEN_MEMSTREAM */ diff --git a/tests/test-ansi-c.sh b/tests/test-ansi-c.sh index e04c23f9..bd5e11ff 100755 --- a/tests/test-ansi-c.sh +++ b/tests/test-ansi-c.sh @@ -35,4 +35,4 @@ set -e # We only really care that the plugin compiled, so we don't # need to run it properly. -nbdkit .libs/test-ansi-c-plugin.so --version +nbdkit .libs/test-ansi-c-plugin.$SOEXT --version diff --git a/tests/test-binary.sh b/tests/test-binary.sh index b3c54d8a..fa82bd57 100755 --- a/tests/test-binary.sh +++ b/tests/test-binary.sh @@ -42,7 +42,8 @@ set -e requires cut --version binary1="$( nbdkit --dump-config | grep ^binary= | cut -d= -f2 )" -binary2="$( ../server/nbdkit --dump-config | grep ^binary= | cut -d= -f2 )" +binary2="$( ../server/nbdkit$EXEEXT --dump-config | + grep ^binary= | cut -d= -f2 )" echo binary1=$binary1 echo binary2=$binary2 diff --git a/tests/test-cxx.sh b/tests/test-cxx.sh index 45a06567..81b5477d 100755 --- a/tests/test-cxx.sh +++ b/tests/test-cxx.sh @@ -36,4 +36,5 @@ set -e # We only really care that the plugin compiled, so we don't # need to run it properly. libs=./.libs -nbdkit --filter=$libs/test-cxx-filter.so $libs/test-cxx-plugin.so --version +nbdkit --filter=$libs/test-cxx-filter.$SOEXT \ + $libs/test-cxx-plugin.$SOEXT --version diff --git a/tests/test-flush.sh b/tests/test-flush.sh index 9b353dff..67e54570 100755 --- a/tests/test-flush.sh +++ b/tests/test-flush.sh @@ -35,7 +35,7 @@ set -x requires nbdsh --version -plugin=.libs/test-flush-plugin.so +plugin=.libs/test-flush-plugin.$SOEXT requires test -f $plugin files="test-flush.err" diff --git a/tests/test-layers.sh b/tests/test-layers.sh index 83d1a9e9..0e3f010a 100755 --- a/tests/test-layers.sh +++ b/tests/test-layers.sh @@ -38,7 +38,7 @@ files="test-layers.out" rm -f $files cleanup_fn rm -f $files -cmd="nbdkit --filter=.libs/test-layers-filter3.so --filter=.libs/test-layers-filter2.so --filter=.libs/test-layers-filter1.so .libs/test-layers-plugin.so" +cmd="nbdkit --filter=.libs/test-layers-filter3.$SOEXT --filter=.libs/test-layers-filter2.$SOEXT --filter=.libs/test-layers-filter1.$SOEXT .libs/test-layers-plugin.$SOEXT" $cmd --help > test-layers.out cat test-layers.out ||: diff --git a/tests/test-shutdown.sh b/tests/test-shutdown.sh index 651fe3c5..231a3876 100755 --- a/tests/test-shutdown.sh +++ b/tests/test-shutdown.sh @@ -36,7 +36,7 @@ set -x requires qemu-img --version requires qemu-io --version -plugin=.libs/test-shutdown-plugin.so +plugin=.libs/test-shutdown-plugin.$SOEXT requires test -f $plugin sock=`mktemp -u` diff --git a/tests/test-stdio.sh b/tests/test-stdio.sh index b8d31367..2cafb6c5 100755 --- a/tests/test-stdio.sh +++ b/tests/test-stdio.sh @@ -35,7 +35,7 @@ set -xe requires nbdsh -c 'exit (not h.supports_uri ())' -plugin=.libs/test-stdio-plugin.so +plugin=.libs/test-stdio-plugin.$SOEXT requires test -f $plugin sock1=`mktemp -u` diff --git a/tests/functions.sh.in b/tests/functions.sh.in index 6dc9b6eb..035bcddd 100644 --- a/tests/functions.sh.in +++ b/tests/functions.sh.in @@ -36,6 +36,8 @@ CXX="@CXX@" OCAMLOPT="@OCAMLOPT@" PYTHON="@PYTHON@" +SOEXT="@SOEXT@" +EXEEXT="@EXEEXT@" # cleanup_fn f [args] # @@ -188,7 +190,7 @@ foreach_plugin () for p in @plugins@; do # Was the plugin built? d="@top_builddir@/plugins/$p" - if [ -f "$d/.libs/nbdkit-$p-plugin.so" ] || + if [ -f "$d/.libs/nbdkit-$p-plugin.$SOEXT" ] || [ -f "$d/nbdkit-$p-plugin" ]; then # Yes so run the test. "$f" "$p" "$@" diff --git a/tests/test-exit-with-parent.c b/tests/test-exit-with-parent.c index 27fe4028..e7e8254d 100644 --- a/tests/test-exit-with-parent.c +++ b/tests/test-exit-with-parent.c @@ -38,9 +38,12 @@ #include <inttypes.h> #include <string.h> #include <unistd.h> +#include <errno.h> #include <sys/types.h> + +#ifdef HAVE_SYS_WAIT_H #include <sys/wait.h> -#include <errno.h> +#endif #include "exit-with-parent.h" #include "test.h" diff --git a/tests/test-layers.c b/tests/test-layers.c index dd826f36..459d05ec 100644 --- a/tests/test-layers.c +++ b/tests/test-layers.c @@ -53,8 +53,14 @@ #include <unistd.h> #include <errno.h> #include <sys/types.h> + +#ifdef HAVE_SYS_SOCKET_H #include <sys/socket.h> +#endif + +#ifdef HAVE_SYS_WAIT_H #include <sys/wait.h> +#endif #include <pthread.h> @@ -71,6 +77,8 @@ #define program_name "nbdkit" #endif +#ifndef WIN32 + static void *start_log_capture (void *); static void log_verify_seen (const char *msg); static void log_verify_seen_in_order (const char *msg, ...) @@ -135,10 +143,10 @@ main (int argc, char *argv[]) * isn't reliably called unless we disable parallel. */ "-t", "1", - "--filter", ".libs/test-layers-filter3.so", - "--filter", ".libs/test-layers-filter2.so", - "--filter", ".libs/test-layers-filter1.so", - ".libs/test-layers-plugin.so", + "--filter", ".libs/test-layers-filter3." SOEXT, + "--filter", ".libs/test-layers-filter2." SOEXT, + "--filter", ".libs/test-layers-filter1." SOEXT, + ".libs/test-layers-plugin." SOEXT, "foo=bar", NULL); perror ("exec: nbdkit"); @@ -787,3 +795,16 @@ log_free (void) log_buf = NULL; log_len = 0; } + +#else /* WIN32 */ + +/* A lot of porting work required for Windows. For now, skip the test. */ +int +main (int argc, char *argv[]) +{ + fprintf (stderr, "%s: test skipped because not ported to Windows.\n", + argv[0]); + exit (77); +} + +#endif /* WIN32 */ diff --git a/tests/test-socket-activation.c b/tests/test-socket-activation.c index d2db8e3e..9f847039 100644 --- a/tests/test-socket-activation.c +++ b/tests/test-socket-activation.c @@ -54,9 +54,18 @@ #include <signal.h> #include <errno.h> #include <sys/types.h> + +#ifdef HAVE_SYS_SOCKET_H #include <sys/socket.h> +#endif + +#ifdef HAVE_SYS_UN_H #include <sys/un.h> +#endif + +#ifdef HAVE_SYS_WAIT_H #include <sys/wait.h> +#endif #include "byte-swapping.h" #include "nbd-protocol.h" diff --git a/tests/test-stdio-plugin.c b/tests/test-stdio-plugin.c index 0a071e17..09382a09 100644 --- a/tests/test-stdio-plugin.c +++ b/tests/test-stdio-plugin.c @@ -46,6 +46,8 @@ #define NBDKIT_API_VERSION 2 #include <nbdkit-plugin.h> +#include "getline.h" + static const char *msg = "input"; /* Check whether stdin/out match /dev/null */ diff --git a/tests/test.c b/tests/test.c index 8eb1a525..3a48daa7 100644 --- a/tests/test.c +++ b/tests/test.c @@ -37,15 +37,22 @@ #include <stdarg.h> #include <string.h> #include <unistd.h> -#include <sys/types.h> -#include <sys/wait.h> #include <signal.h> #include <errno.h> + #undef NDEBUG /* Keep test strong even for nbdkit built without assertions */ #include <assert.h> +#include <sys/types.h> + +#ifdef HAVE_SYS_WAIT_H +#include <sys/wait.h> +#endif + #include "test.h" +#ifndef WIN32 + /* 'test_start_nbdkit' below makes assumptions about the format of * these strings. */ @@ -218,3 +225,18 @@ test_start_nbdkit (const char *arg, ...) return 0; } + +#else /* WIN32 */ + +/* All of the above code will require a lot of porting work for + * Windows. At the moment the test gets skipped. + */ +int +test_start_nbdkit (const char *arg, ...) +{ + fprintf (stderr, "%s: test skipped because not ported to Windows.\n", + program_name); + exit (77); +} + +#endif diff --git a/.gitignore b/.gitignore index 6919a4d7..3cab4ff3 100644 --- a/.gitignore +++ b/.gitignore @@ -106,6 +106,7 @@ plugins/*/*.3 /tests/file-data /tests/functions.sh /tests/keys.psk +/tests/nbdkit /tests/partition-disk /tests/pki /tests/split1 -- 2.27.0
participants (2)
-
Eric Blake -
Richard W.M. Jones