Also available here: https://github.com/rwmjones/nbdkit/tree/2020-windows-mingw This is the port to Windows using native Windows APIs (not MSYS or Cygwin). This patch series is at the point where it basically now works. I can run the server with the memory plugin, and access it remotely using guestfish, creating filesystems and so on without any apparent problems. Nevertheless there are many missing features (see TODO). It would be really nice to have a native Windows file plugin. It's hard to imagine an NBD server being taken seriously that cannot serve files! The major impediment to getting this upstream is probably the requirement for libnbdkit.so (first patch). Although this is optional and doesn't break backwards compatibility it's a rather large change especially as I hope we're coming towards the end of the 1.22 development cycle. So this is more like 1.24 material. It would also be nice if we were automatically doing CI on this code so it doesn't regress. While investigating this topic I saw that gnutls is using gitlab CI to cross-compile and test with mingw-w64: https://gitlab.com/gnutls/gnutls/-/blob/master/.gitlab-ci.yml Rich.
Richard W.M. Jones
2020-Aug-18 10:50 UTC
[Libguestfs] [PATCH nbdkit 1/9] server: Add libnbdkit.so.
This essentially turns the whole of nbdkit into a library. There is a rump nbdkit program left which simply contains a main() function that forwards to the nbdkit_main() function in the library. The reason for this is to allow nbdkit to be compiled on Windows, because Windows does not allow shared libraries to contain any undefined symbols. nbdkit previously relied on undefined symbols in all plugins and filters (eg. nbdkit_parse_int) which get resolved at run time by the nbdkit program. In order to make this work on Windows we need to have a new library (libnbdkit.so on Linux, but probably called something like LIBNBDKIT.DLL on Windows) which will contain these symbols, and plugins can then be compiled with -lnbdkit so they will link with this library, hence no undefined symbols. Note this change is backwards compatible. Because the rump nbdkit binary links with -lnbdkit it still contains and reexports all the symbols, so plugins and filters which don't explicitly link with -lnbdkit will still be loadable (on existing platforms). --- server/Makefile.am | 21 ++++++++------ server/main.c | 2 +- server/nbdkit.c | 46 ++++++++++++++++++++++++++++++ server/nbdkit.syms | 1 + tests/test-nbdkit-backend-debug.sh | 24 ++++++++-------- wrapper.c | 10 +++++-- 6 files changed, 80 insertions(+), 24 deletions(-) diff --git a/server/Makefile.am b/server/Makefile.am index 58b22341..8cfa0115 100644 --- a/server/Makefile.am +++ b/server/Makefile.am @@ -34,8 +34,12 @@ include $(top_srcdir)/common-rules.mk EXTRA_DIST = nbdkit.syms sbin_PROGRAMS = nbdkit +nbdkit_SOURCES = nbdkit.c +nbdkit_CFLAGS = $(WARNINGS_CFLAGS) +nbdkit_LDADD = libnbdkit.la -nbdkit_SOURCES = \ +lib_LTLIBRARIES = libnbdkit.la +libnbdkit_la_SOURCES = \ backend.c \ background.c \ captive.c \ @@ -70,10 +74,10 @@ nbdkit_SOURCES = \ $(top_srcdir)/include/nbdkit-filter.h \ $(NULL) if ENABLE_LIBFUZZER -nbdkit_SOURCES += fuzzer.c +libnbdkit_la_SOURCES += fuzzer.c endif -nbdkit_CPPFLAGS = \ +libnbdkit_la_CPPFLAGS = \ -Dbindir=\"$(bindir)\" \ -Dlibdir=\"$(libdir)\" \ -Dmandir=\"$(mandir)\" \ @@ -86,21 +90,22 @@ nbdkit_CPPFLAGS = \ -I$(top_srcdir)/common/protocol \ -I$(top_srcdir)/common/utils \ $(NULL) -nbdkit_CFLAGS = \ +libnbdkit_la_CFLAGS = \ $(PTHREAD_CFLAGS) \ $(WARNINGS_CFLAGS) \ $(GNUTLS_CFLAGS) \ $(LIBSELINUX_CFLAGS) \ $(VALGRIND_CFLAGS) \ $(NULL) -nbdkit_LDADD = \ +libnbdkit_la_LIBADD = \ $(GNUTLS_LIBS) \ $(LIBSELINUX_LIBS) \ $(DL_LIBS) \ $(top_builddir)/common/protocol/libprotocol.la \ $(top_builddir)/common/utils/libutils.la \ $(NULL) -nbdkit_LDFLAGS = \ +libnbdkit_la_LDFLAGS = \ + -shared $(NO_UNDEFINED_ON_WINDOWS) \ $(PTHREAD_LIBS) \ $(DL_LDFLAGS) \ $(NULL) @@ -109,7 +114,7 @@ if USE_LINKER_SCRIPT_FOR_SERVER # adds loads of fuzzer and ASAN-related symbols that are required by # the plugins but which our linker script tries to hide. if !ENABLE_LIBFUZZER -nbdkit_LDFLAGS += -Wl,--version-script=$(srcdir)/nbdkit.syms +libnbdkit_la_LDFLAGS += -Wl,--version-script=$(srcdir)/nbdkit.syms endif endif @@ -118,7 +123,7 @@ endif BUILT_SOURCES = synopsis.c EXTRA_DIST += synopsis.c -EXTRA_nbdkit_DEPENDENCIES = synopsis.c +EXTRA_libnbdkit_la_DEPENDENCIES = synopsis.c CLEANFILES += synopsis.c main.c: synopsis.c synopsis.c: $(top_srcdir)/docs/synopsis.txt diff --git a/server/main.c b/server/main.c index 17c4c324..bb7f863e 100644 --- a/server/main.c +++ b/server/main.c @@ -171,7 +171,7 @@ dump_config (void) } int -main (int argc, char *argv[]) +nbdkit_main (int argc, char *argv[]) { int c; bool help = false, version = false, dump_plugin = false; diff --git a/server/nbdkit.c b/server/nbdkit.c new file mode 100644 index 00000000..e2e55cbb --- /dev/null +++ b/server/nbdkit.c @@ -0,0 +1,46 @@ +/* nbdkit + * Copyright (C) 2013-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> + +extern int nbdkit_main (int argc, char *argv[]); + +int +main (int argc, char *argv[]) +{ + /* This does nothing except call into the real main function in + * libnbdkit.so. + */ + return nbdkit_main (argc, argv); +} diff --git a/server/nbdkit.syms b/server/nbdkit.syms index a67669b7..a516cc0f 100644 --- a/server/nbdkit.syms +++ b/server/nbdkit.syms @@ -54,6 +54,7 @@ nbdkit_extents_new; nbdkit_get_extent; nbdkit_is_tls; + nbdkit_main; nbdkit_nanosleep; nbdkit_parse_bool; nbdkit_parse_int8_t; diff --git a/tests/test-nbdkit-backend-debug.sh b/tests/test-nbdkit-backend-debug.sh index 3a28b756..1533ba44 100755 --- a/tests/test-nbdkit-backend-debug.sh +++ b/tests/test-nbdkit-backend-debug.sh @@ -49,10 +49,10 @@ nbdkit -U - \ --run "qemu-img convert \$nbd $out" |& tee $debug # Should contain all debugging messages. -grep '^nbdkit:.*debug: nofilter: open' $debug -grep '^nbdkit:.*debug: memory: open' $debug -grep '^nbdkit:.*debug: nofilter: pread' $debug -grep '^nbdkit:.*debug: memory: pread' $debug +grep 'nbdkit:.*debug: nofilter: open' $debug +grep 'nbdkit:.*debug: memory: open' $debug +grep 'nbdkit:.*debug: nofilter: pread' $debug +grep 'nbdkit:.*debug: memory: pread' $debug nbdkit -U - \ -v -D nbdkit.backend.controlpath=0 \ @@ -61,10 +61,10 @@ nbdkit -U - \ --run "qemu-img convert \$nbd $out" |& tee $debug # Should contain only datapath messages. -grep -v '^nbdkit:.*debug: nofilter: open' $debug -grep -v '^nbdkit:.*debug: memory: open' $debug -grep '^nbdkit:.*debug: nofilter: pread' $debug -grep '^nbdkit:.*debug: memory: pread' $debug +grep -v 'nbdkit:.*debug: nofilter: open' $debug +grep -v 'nbdkit:.*debug: memory: open' $debug +grep 'nbdkit:.*debug: nofilter: pread' $debug +grep 'nbdkit:.*debug: memory: pread' $debug nbdkit -U - \ -v -D nbdkit.backend.datapath=0 \ @@ -73,7 +73,7 @@ nbdkit -U - \ --run "qemu-img convert \$nbd $out" |& tee $debug # Should contain only controlpath messages. -grep '^nbdkit:.*debug: nofilter: open' $debug -grep '^nbdkit:.*debug: memory: open' $debug -grep -v '^nbdkit:.*debug: nofilter: pread' $debug -grep -v '^nbdkit:.*debug: memory: pread' $debug +grep 'nbdkit:.*debug: nofilter: open' $debug +grep 'nbdkit:.*debug: memory: open' $debug +grep -v 'nbdkit:.*debug: nofilter: pread' $debug +grep -v 'nbdkit:.*debug: memory: pread' $debug diff --git a/wrapper.c b/wrapper.c index c27afae0..7029c2cd 100644 --- a/wrapper.c +++ b/wrapper.c @@ -168,12 +168,16 @@ main (int argc, char *argv[]) } } - /* Needed for plugins written in OCaml. */ + /* As well as being required by nbdkit, this is also needed for + * plugins written in OCaml. + */ s = getenv ("LD_LIBRARY_PATH"); if (s) - r = asprintf (&s, "%s/plugins/ocaml/.libs:%s", builddir, s); + r = asprintf (&s, "%s/server/.libs:%s/plugins/ocaml/.libs:%s", + builddir, builddir, s); else - r = asprintf (&s, "%s/plugins/ocaml/.libs", builddir); + r = asprintf (&s, "%s/server/.libs:%s/plugins/ocaml/.libs", + builddir, builddir); if (r < 0) { perror ("asprintf"); exit (EXIT_FAILURE); -- 2.27.0
Richard W.M. Jones
2020-Aug-18 10:50 UTC
[Libguestfs] [PATCH nbdkit 2/9] build: On Windows only, link all plugins and filters with -lnbdkit.
--- 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 | 5 ++++- plugins/tmpdisk/Makefile.am | 7 ++++--- plugins/torrent/Makefile.am | 11 ++++++----- plugins/vddk/Makefile.am | 1 + plugins/zero/Makefile.am | 3 +++ tests/Makefile.am | 10 ++++++++++ 72 files changed, 139 insertions(+), 17 deletions(-) diff --git a/configure.ac b/configure.ac index 84e50e72..1ac0eab7 100644 --- a/configure.ac +++ b/configure.ac @@ -457,11 +457,13 @@ AS_CASE([$host_os], [mingw*|msys*|cygwin*], [ is_windows=yes NO_UNDEFINED_ON_WINDOWS="-no-undefined" + LINK_LIBNBDKIT_ON_WINDOWS='$(top_builddir)/server/libnbdkit.la' ], [is_windows=no] ) AC_MSG_RESULT([$is_windows]) AC_SUBST([NO_UNDEFINED_ON_WINDOWS]) +AC_SUBST([LINK_LIBNBDKIT_ON_WINDOWS]) AC_SEARCH_LIBS([getaddrinfo], [network socket]) diff --git a/filters/blocksize/Makefile.am b/filters/blocksize/Makefile.am index ea51246a..dcb9352c 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 \ + $(LINK_LIBNBDKIT_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/filters/cache/Makefile.am b/filters/cache/Makefile.am index 200cda15..a98be192 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 \ + $(LINK_LIBNBDKIT_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/filters/cacheextents/Makefile.am b/filters/cacheextents/Makefile.am index 2f7a689b..8dfc067e 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 \ + $(LINK_LIBNBDKIT_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/filters/cow/Makefile.am b/filters/cow/Makefile.am index 4ff08a44..02e2c504 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 \ + $(LINK_LIBNBDKIT_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/filters/ddrescue/Makefile.am b/filters/ddrescue/Makefile.am index 79bbad9c..f8aeecfe 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 \ + $(LINK_LIBNBDKIT_ON_WINDOWS) \ $(GNUTLS_LIBS) \ $(NULL) diff --git a/filters/delay/Makefile.am b/filters/delay/Makefile.am index 470c6062..e7b097eb 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 = \ + $(LINK_LIBNBDKIT_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..c638085b 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 \ + $(LINK_LIBNBDKIT_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/filters/exitlast/Makefile.am b/filters/exitlast/Makefile.am index 17603951..71596799 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 = \ + $(LINK_LIBNBDKIT_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..5eb53562 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 \ + $(LINK_LIBNBDKIT_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..975cb07f 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 \ + $(LINK_LIBNBDKIT_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/filters/fua/Makefile.am b/filters/fua/Makefile.am index 9fd056df..7ba329b2 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 = \ + $(LINK_LIBNBDKIT_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..88c4041e 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 \ + $(LINK_LIBNBDKIT_ON_WINDOWS) \ $(ZLIB_LIBS) \ $(NULL) nbdkit_gzip_filter_la_LDFLAGS = \ diff --git a/filters/ip/Makefile.am b/filters/ip/Makefile.am index 16d23057..cf990a86 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 \ + $(LINK_LIBNBDKIT_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/filters/limit/Makefile.am b/filters/limit/Makefile.am index c721700c..0b9b6f2d 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 \ + $(LINK_LIBNBDKIT_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/filters/log/Makefile.am b/filters/log/Makefile.am index f2c4d813..e7670434 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 \ + $(LINK_LIBNBDKIT_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/filters/nocache/Makefile.am b/filters/nocache/Makefile.am index c3cb35f7..8f9022bb 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 = \ + $(LINK_LIBNBDKIT_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..5adcb2cc 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 = \ + $(LINK_LIBNBDKIT_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..a338efce 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 = \ + $(LINK_LIBNBDKIT_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..22322dd6 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 = \ + $(LINK_LIBNBDKIT_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..3611368c 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 = \ + $(LINK_LIBNBDKIT_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..708276fb 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 \ + $(LINK_LIBNBDKIT_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/filters/partition/Makefile.am b/filters/partition/Makefile.am index 49e3e213..4fb70c7a 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 \ + $(LINK_LIBNBDKIT_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/filters/pause/Makefile.am b/filters/pause/Makefile.am index 3f83eb03..d60bbe7d 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 \ + $(LINK_LIBNBDKIT_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..bf96c4d2 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 \ + $(LINK_LIBNBDKIT_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..a2c00624 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 \ + $(LINK_LIBNBDKIT_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/filters/retry/Makefile.am b/filters/retry/Makefile.am index 1011bff8..0d783dad 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 \ + $(LINK_LIBNBDKIT_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/filters/stats/Makefile.am b/filters/stats/Makefile.am index be06a08d..a0c1275d 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 \ + $(LINK_LIBNBDKIT_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/filters/swab/Makefile.am b/filters/swab/Makefile.am index 7acaa6a6..26d40403 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 \ + $(LINK_LIBNBDKIT_ON_WINDOWS) \ $(GNUTLS_LIBS) \ $(NULL) diff --git a/filters/tar/Makefile.am b/filters/tar/Makefile.am index 30e973cc..9c67d0d9 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 \ + $(LINK_LIBNBDKIT_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/filters/tls-fallback/Makefile.am b/filters/tls-fallback/Makefile.am index 516c2ccf..0cd5bd1b 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 = \ + $(LINK_LIBNBDKIT_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..ddbdb052 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 \ + $(LINK_LIBNBDKIT_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/filters/xz/Makefile.am b/filters/xz/Makefile.am index 63bbd1c5..8712d2d8 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 \ + $(LINK_LIBNBDKIT_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..947b92e4 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 \ + $(LINK_LIBNBDKIT_ON_WINDOWS) \ $(DL_LIBS) \ $(NULL) diff --git a/plugins/cdi/Makefile.am b/plugins/cdi/Makefile.am index 9ce98d5f..1c2904d8 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 \ + $(LINK_LIBNBDKIT_ON_WINDOWS) \ $(JANSSON_LIBS) \ $(NULL) diff --git a/plugins/curl/Makefile.am b/plugins/curl/Makefile.am index 29183f03..175f034e 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 \ + $(LINK_LIBNBDKIT_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 de6e80bb..f4684915 100644 --- a/plugins/data/Makefile.am +++ b/plugins/data/Makefile.am @@ -62,6 +62,7 @@ nbdkit_data_plugin_la_LDFLAGS = \ nbdkit_data_plugin_la_LIBADD = \ $(top_builddir)/common/allocators/liballocators.la \ $(top_builddir)/common/utils/libutils.la \ + $(LINK_LIBNBDKIT_ON_WINDOWS) \ $(GNUTLS_LIBS) \ $(NULL) diff --git a/plugins/eval/Makefile.am b/plugins/eval/Makefile.am index 4ea8d7d4..4b2aa598 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 \ + $(LINK_LIBNBDKIT_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..12aca60d 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 = \ + $(LINK_LIBNBDKIT_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..d78ab386 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 = \ + $(LINK_LIBNBDKIT_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..756c0d2f 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 = \ + $(LINK_LIBNBDKIT_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..30999a52 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 \ + $(LINK_LIBNBDKIT_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/plugins/floppy/Makefile.am b/plugins/floppy/Makefile.am index 33d026fa..6636caf2 100644 --- a/plugins/floppy/Makefile.am +++ b/plugins/floppy/Makefile.am @@ -60,6 +60,7 @@ nbdkit_floppy_plugin_la_LDFLAGS = \ nbdkit_floppy_plugin_la_LIBADD = \ $(top_builddir)/common/regions/libregions.la \ $(top_builddir)/common/utils/libutils.la \ + $(LINK_LIBNBDKIT_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/plugins/full/Makefile.am b/plugins/full/Makefile.am index 97101d18..3d0d5c36 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 = \ + $(LINK_LIBNBDKIT_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..120e3c7a 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 \ + $(LINK_LIBNBDKIT_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..ed3173ed 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 = \ + $(LINK_LIBNBDKIT_ON_WINDOWS) \ $(ZLIB_LIBS) \ $(NULL) nbdkit_gzip_plugin_la_LDFLAGS = \ diff --git a/plugins/info/Makefile.am b/plugins/info/Makefile.am index dc55d93c..617b309c 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 = \ + $(LINK_LIBNBDKIT_ON_WINDOWS) \ $(GNUTLS_LIBS) \ $(NULL) diff --git a/plugins/iso/Makefile.am b/plugins/iso/Makefile.am index 1f1f8416..ff3cfc47 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 \ + $(LINK_LIBNBDKIT_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/plugins/libvirt/Makefile.am b/plugins/libvirt/Makefile.am index e750e544..c26bb80f 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 = \ + $(LINK_LIBNBDKIT_ON_WINDOWS) \ $(LIBVIRT_LIBS) \ $(NULL) nbdkit_libvirt_plugin_la_LDFLAGS = \ diff --git a/plugins/linuxdisk/Makefile.am b/plugins/linuxdisk/Makefile.am index 7557ee5e..0121299d 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 \ + $(LINK_LIBNBDKIT_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..f0e2b650 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 = \ + $(LINK_LIBNBDKIT_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 a88c45c9..2270e6fe 100644 --- a/plugins/memory/Makefile.am +++ b/plugins/memory/Makefile.am @@ -53,6 +53,7 @@ nbdkit_memory_plugin_la_LDFLAGS = \ nbdkit_memory_plugin_la_LIBADD = \ $(top_builddir)/common/allocators/liballocators.la \ $(top_builddir)/common/utils/libutils.la \ + $(LINK_LIBNBDKIT_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/plugins/nbd/Makefile.am b/plugins/nbd/Makefile.am index 671ae678..1d44b6df 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 \ + $(LINK_LIBNBDKIT_ON_WINDOWS) \ $(LIBNBD_LIBS) \ $(NULL) diff --git a/plugins/null/Makefile.am b/plugins/null/Makefile.am index b07a70a4..1c730f48 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 = \ + $(LINK_LIBNBDKIT_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..ec7ddd4a 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 \ + $(LINK_LIBNBDKIT_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/plugins/partitioning/Makefile.am b/plugins/partitioning/Makefile.am index d8cf9e29..36720339 100644 --- a/plugins/partitioning/Makefile.am +++ b/plugins/partitioning/Makefile.am @@ -61,6 +61,7 @@ nbdkit_partitioning_plugin_la_LIBADD = \ $(top_builddir)/common/gpt/libgpt.la \ $(top_builddir)/common/regions/libregions.la \ $(top_builddir)/common/utils/libutils.la \ + $(LINK_LIBNBDKIT_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/plugins/pattern/Makefile.am b/plugins/pattern/Makefile.am index dfbbdafa..50806d0c 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 = \ + $(LINK_LIBNBDKIT_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..b5628241 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 \ + $(LINK_LIBNBDKIT_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..aacc6f22 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 \ + $(LINK_LIBNBDKIT_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..35a6594f 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 = \ + $(LINK_LIBNBDKIT_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..b0ae24c8 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 = \ + $(LINK_LIBNBDKIT_ON_WINDOWS) \ $(RUBY_LIBS) \ $(NULL) nbdkit_ruby_plugin_la_LDFLAGS = \ diff --git a/plugins/sh/Makefile.am b/plugins/sh/Makefile.am index 77a3abde..4274b6e8 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 \ + $(LINK_LIBNBDKIT_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..045c02f2 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 \ + $(LINK_LIBNBDKIT_ON_WINDOWS) \ $(NULL) if HAVE_POD diff --git a/plugins/ssh/Makefile.am b/plugins/ssh/Makefile.am index 8b2e9293..c2b0d1eb 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 \ + $(LINK_LIBNBDKIT_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..ef50ce58 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 = \ + $(LINK_LIBNBDKIT_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..1db0c8f5 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 \ + $(LINK_LIBNBDKIT_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 b4995e24..dcb78ebc 100644 --- a/plugins/tcl/Makefile.am +++ b/plugins/tcl/Makefile.am @@ -52,10 +52,13 @@ nbdkit_tcl_plugin_la_CFLAGS = \ $(WARNINGS_CFLAGS) \ $(TCL_CFLAGS) \ $(NULL) +nbdkit_tcl_plugin_la_LIBADD = \ + $(LINK_LIBNBDKIT_ON_WINDOWS) \ + $(TCL_LIBS) \ + $(NULL) nbdkit_tcl_plugin_la_LDFLAGS = \ -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ -Wl,--version-script=$(top_srcdir)/plugins/plugins.syms \ - $(TCL_LIBS) \ $(NULL) if HAVE_POD diff --git a/plugins/tmpdisk/Makefile.am b/plugins/tmpdisk/Makefile.am index 69ae85e0..5542143e 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 \ + $(LINK_LIBNBDKIT_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..2afc39cc 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 \ + $(LINK_LIBNBDKIT_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..95da626a 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 \ + $(LINK_LIBNBDKIT_ON_WINDOWS) \ $(DL_LIBS) \ $(NULL) nbdkit_vddk_plugin_la_LDFLAGS = \ diff --git a/plugins/zero/Makefile.am b/plugins/zero/Makefile.am index 0ec1c396..983e17d3 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 = \ + $(LINK_LIBNBDKIT_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 f871ac68..43783f63 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -272,6 +272,7 @@ 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 = $(LINK_LIBNBDKIT_ON_WINDOWS) # check_LTLIBRARIES won't build a shared library (see automake manual). # So we have to do this and add a dependency. @@ -291,6 +292,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 = $(LINK_LIBNBDKIT_ON_WINDOWS) # check_LTLIBRARIES won't build a shared library (see automake manual). # So we have to do this and add a dependency. @@ -310,6 +312,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 = $(LINK_LIBNBDKIT_ON_WINDOWS) endif HAVE_PLUGINS @@ -364,6 +367,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 = $(LINK_LIBNBDKIT_ON_WINDOWS) endif CAN_TEST_ANSI_C if HAVE_CXX @@ -389,6 +393,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 = $(LINK_LIBNBDKIT_ON_WINDOWS) test_cxx_filter_la_SOURCES = \ test-cxx-filter.cpp \ @@ -403,6 +408,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 = $(LINK_LIBNBDKIT_ON_WINDOWS) endif HAVE_CXX # Exit with parent test. @@ -1231,6 +1237,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 = $(LINK_LIBNBDKIT_ON_WINDOWS) test_layers_filter1_la_SOURCES = \ test-layers-filter.c \ @@ -1243,6 +1250,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 = $(LINK_LIBNBDKIT_ON_WINDOWS) test_layers_filter2_la_SOURCES = \ test-layers-filter.c \ @@ -1255,6 +1263,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 = $(LINK_LIBNBDKIT_ON_WINDOWS) test_layers_filter3_la_SOURCES = \ test-layers-filter.c \ @@ -1267,6 +1276,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 = $(LINK_LIBNBDKIT_ON_WINDOWS) # blocksize filter test. TESTS += test-blocksize.sh test-blocksize-extents.sh -- 2.27.0
Richard W.M. Jones
2020-Aug-18 10:50 UTC
[Libguestfs] [PATCH nbdkit 3/9] server: Add general replacements for missing functions using LIBOBJS.
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 written by me 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 | 53 ++++++++++++++++ common/replacements/win32/Makefile.am | 46 ++++++++++++++ server/Makefile.am | 3 + common/replacements/getline.h | 50 +++++++++++++++ common/replacements/realpath.h | 50 +++++++++++++++ common/replacements/strndup.h | 49 +++++++++++++++ common/replacements/syslog.h | 67 ++++++++++++++++++++ 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 | 62 ++++++++++++++++++ common/replacements/realpath.c | 81 ++++++++++++++++++++++++ common/replacements/strndup.c | 64 +++++++++++++++++++ common/replacements/syslog.c | 62 ++++++++++++++++++ common/replacements/vsyslog.c | 74 ++++++++++++++++++++++ common/replacements/win32/nbdkit-cat.mc | 6 ++ .gitignore | 4 ++ 22 files changed, 833 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index 1ac0eab7..aa586997 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], @@ -464,6 +475,15 @@ AS_CASE([$host_os], AC_MSG_RESULT([$is_windows]) AC_SUBST([NO_UNDEFINED_ON_WINDOWS]) AC_SUBST([LINK_LIBNBDKIT_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]) @@ -1107,6 +1127,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..5051099a --- /dev/null +++ b/common/replacements/Makefile.am @@ -0,0 +1,53 @@ +# nbdkit +# Copyright (C) 2019 Red Hat Inc. +# All rights reserved. +# +# 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..f4ec025b --- /dev/null +++ b/common/replacements/win32/Makefile.am @@ -0,0 +1,46 @@ +# nbdkit +# Copyright (C) 2019 Red Hat Inc. +# All rights reserved. +# +# 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 8cfa0115..0b693f21 100644 --- a/server/Makefile.am +++ b/server/Makefile.am @@ -88,6 +88,7 @@ libnbdkit_la_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) libnbdkit_la_CFLAGS = \ @@ -103,6 +104,7 @@ libnbdkit_la_LIBADD = \ $(DL_LIBS) \ $(top_builddir)/common/protocol/libprotocol.la \ $(top_builddir)/common/utils/libutils.la \ + $(top_builddir)/common/replacements/libcompat.la \ $(NULL) libnbdkit_la_LDFLAGS = \ -shared $(NO_UNDEFINED_ON_WINDOWS) \ @@ -152,6 +154,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..a9e1024a --- /dev/null +++ b/common/replacements/getline.h @@ -0,0 +1,50 @@ +/* nbdkit + * Copyright (C) 2019 Red Hat Inc. + * All rights reserved. + * + * 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> + +#ifdef HAVE_GETLINE + +#include <stdio.h> + +#else + +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..14fee810 --- /dev/null +++ b/common/replacements/realpath.h @@ -0,0 +1,50 @@ +/* nbdkit + * Copyright (C) 2019 Red Hat Inc. + * All rights reserved. + * + * 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> + +#ifdef HAVE_REALPATH + +#include <limits.h> +#include <stdlib.h> + +#else + +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..464ce954 --- /dev/null +++ b/common/replacements/strndup.h @@ -0,0 +1,49 @@ +/* nbdkit + * Copyright (C) 2019 Red Hat Inc. + * All rights reserved. + * + * 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> + +#ifdef HAVE_STRNDUP + +#include <string.h> + +#else + +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..e4d76677 --- /dev/null +++ b/common/replacements/syslog.h @@ -0,0 +1,67 @@ +/* nbdkit + * Copyright (C) 2019 Red Hat Inc. + * All rights reserved. + * + * 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 bb7f863e..a96ac88b 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..2f601655 --- /dev/null +++ b/common/replacements/openlog.c @@ -0,0 +1,62 @@ +/* nbdkit + * Copyright (C) 2019 Red Hat Inc. + * All rights reserved. + * + * 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..622ee7ea --- /dev/null +++ b/common/replacements/realpath.c @@ -0,0 +1,81 @@ +/* nbdkit + * Copyright (C) 2019 Red Hat Inc. + * All rights reserved. + * + * 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..de1c27c2 --- /dev/null +++ b/common/replacements/strndup.c @@ -0,0 +1,64 @@ +/* nbdkit + * Copyright (C) 2019 Red Hat Inc. + * All rights reserved. + * + * 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 strndup for platforms which lack this function. */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#ifndef HAVE_STRNDUP + +#include "strndup.h" + +char * +strndup(const char *s, size_t n) +{ + size_t len = strlen (s); + char *ret; + + if (len > n) + len = n; + + ret = malloc (len+1); + if (ret == NULL) + return NULL; + memcpy (ret, s, len); + ret[len] = '\0'; + + return ret; +} + +#endif /* !HAVE_STRNDUP */ diff --git a/common/replacements/syslog.c b/common/replacements/syslog.c new file mode 100644 index 00000000..6f41cbd8 --- /dev/null +++ b/common/replacements/syslog.c @@ -0,0 +1,62 @@ +/* nbdkit + * Copyright (C) 2019 Red Hat Inc. + * All rights reserved. + * + * 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..331aba0f --- /dev/null +++ b/common/replacements/vsyslog.c @@ -0,0 +1,74 @@ +/* nbdkit + * Copyright (C) 2019 Red Hat Inc. + * All rights reserved. + * + * 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..687a835d --- /dev/null +++ b/common/replacements/win32/nbdkit-cat.mc @@ -0,0 +1,6 @@ +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
Richard W.M. Jones
2020-Aug-18 10:50 UTC
[Libguestfs] [PATCH nbdkit 4/9] data: Use replacement function for strndup.
--- 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 f4684915..eea36ee4 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 \ $(LINK_LIBNBDKIT_ON_WINDOWS) \ $(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
Richard W.M. Jones
2020-Aug-18 10:50 UTC
[Libguestfs] [PATCH nbdkit 5/9] memory: Use replacement function for strndup.
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 2270e6fe..4d96b1e7 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 \ $(LINK_LIBNBDKIT_ON_WINDOWS) \ $(NULL) -- 2.27.0
Richard W.M. Jones
2020-Aug-18 10:50 UTC
[Libguestfs] [PATCH nbdkit 6/9] lib: Use replacement strategy for get_current_dir_name.
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 | 10 ++++ plugins/floppy/Makefile.am | 1 + common/replacements/get_current_dir_name.h | 49 +++++++++++++++++++ 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, 69 insertions(+), 17 deletions(-) diff --git a/configure.ac b/configure.ac index aa586997..8c0398fe 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 5051099a..5d73ac35 100644 --- a/common/replacements/Makefile.am +++ b/common/replacements/Makefile.am @@ -40,6 +40,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 \ @@ -51,3 +53,11 @@ 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.h +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 6636caf2..84cedd2b 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..95d4d473 --- /dev/null +++ b/common/replacements/get_current_dir_name.h @@ -0,0 +1,49 @@ +/* nbdkit + * Copyright (C) 2018 Red Hat Inc. + * All rights reserved. + * + * 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
Richard W.M. Jones
2020-Aug-18 10:50 UTC
[Libguestfs] [PATCH nbdkit 7/9] server: Add hand-written replacement for poll for Windows.
--- 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 | 106 ++++++++++++++++++++++++++++++++ 6 files changed, 171 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 8c0398fe..bd9bd65f 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 5d73ac35..5abb6c2b 100644 --- a/common/replacements/Makefile.am +++ b/common/replacements/Makefile.am @@ -46,6 +46,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..c6da5f2a --- /dev/null +++ b/common/replacements/poll.c @@ -0,0 +1,106 @@ +/* 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> + +/* Windows doesn't have poll. It has something called WSAPoll in + * Winsock, but even MSFT admit it is broken. Gnulib contains an + * elaborate emulation of poll written by Paolo, 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, nfds = 0, r; + fd_set readfds, writefds; + struct timeval tv, *tvp; + + 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); + if (fds[i].fd > nfds) + nfds = fds[i].fd; + fds[i].revents = 0; + } + nfds++; + + if (timeout >= 0) { + tv.tv_sec = timeout / 1000; + tv.tv_usec = timeout % 1000; + tvp = &tv; + } + else + tvp = NULL; + + r = select (nfds, &readfds, &writefds, NULL, tvp); + if (r == -1) + 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
Richard W.M. Jones
2020-Aug-18 10:50 UTC
[Libguestfs] [PATCH nbdkit 8/9] include: Prefix all exports with NBDKIT_DLLEXPORT.
This is #defined as empty at the moment, but it allows the Windows port to define this __declspec(dllexport), which is necessary for symbols to be exported in DLLs. --- include/nbdkit-common.h | 86 ++++++++++++++++++++++++----------------- include/nbdkit-filter.h | 42 +++++++++++++------- include/nbdkit-plugin.h | 6 +-- server/main.c | 2 + 4 files changed, 83 insertions(+), 53 deletions(-) diff --git a/include/nbdkit-common.h b/include/nbdkit-common.h index d38b37d2..8684b95a 100644 --- a/include/nbdkit-common.h +++ b/include/nbdkit-common.h @@ -55,6 +55,8 @@ extern "C" { #define ATTRIBUTE_FORMAT_PRINTF(fmtpos, argpos) #endif +#define NBDKIT_DLLEXPORT + #define NBDKIT_THREAD_MODEL_SERIALIZE_CONNECTIONS 0 #define NBDKIT_THREAD_MODEL_SERIALIZE_ALL_REQUESTS 1 #define NBDKIT_THREAD_MODEL_SERIALIZE_REQUESTS 2 @@ -76,49 +78,63 @@ extern "C" { #define NBDKIT_EXTENT_HOLE (1<<0) /* Same as NBD_STATE_HOLE */ #define NBDKIT_EXTENT_ZERO (1<<1) /* Same as NBD_STATE_ZERO */ -extern void nbdkit_error (const char *msg, ...) ATTRIBUTE_FORMAT_PRINTF (1, 2); -extern void nbdkit_verror (const char *msg, va_list args) +extern NBDKIT_DLLEXPORT void nbdkit_error (const char *msg, ...) + ATTRIBUTE_FORMAT_PRINTF (1, 2); +extern NBDKIT_DLLEXPORT void nbdkit_verror (const char *msg, va_list args) ATTRIBUTE_FORMAT_PRINTF (1, 0); -extern void nbdkit_debug (const char *msg, ...) ATTRIBUTE_FORMAT_PRINTF (1, 2); -extern void nbdkit_vdebug (const char *msg, va_list args) +extern NBDKIT_DLLEXPORT void nbdkit_debug (const char *msg, ...) + ATTRIBUTE_FORMAT_PRINTF (1, 2); +extern NBDKIT_DLLEXPORT void nbdkit_vdebug (const char *msg, va_list args) ATTRIBUTE_FORMAT_PRINTF (1, 0); -extern char *nbdkit_absolute_path (const char *path); -extern int64_t nbdkit_parse_size (const char *str); -extern int nbdkit_parse_bool (const char *str); -extern int nbdkit_parse_int (const char *what, const char *str, - int *r); -extern int nbdkit_parse_unsigned (const char *what, const char *str, - unsigned *r); -extern int nbdkit_parse_int8_t (const char *what, const char *str, - int8_t *r); -extern int nbdkit_parse_uint8_t (const char *what, const char *str, - uint8_t *r); -extern int nbdkit_parse_int16_t (const char *what, const char *str, - int16_t *r); -extern int nbdkit_parse_uint16_t (const char *what, const char *str, - uint16_t *r); -extern int nbdkit_parse_int32_t (const char *what, const char *str, - int32_t *r); -extern int nbdkit_parse_uint32_t (const char *what, const char *str, - uint32_t *r); -extern int nbdkit_parse_int64_t (const char *what, const char *str, - int64_t *r); -extern int nbdkit_parse_uint64_t (const char *what, const char *str, - uint64_t *r); -extern int nbdkit_stdio_safe (void); -extern int nbdkit_read_password (const char *value, char **password); -extern char *nbdkit_realpath (const char *path); -extern int nbdkit_nanosleep (unsigned sec, unsigned nsec); -extern int nbdkit_peer_name (struct sockaddr *addr, socklen_t *addrlen); -extern void nbdkit_shutdown (void); +extern NBDKIT_DLLEXPORT char *nbdkit_absolute_path (const char *path); +extern NBDKIT_DLLEXPORT int64_t nbdkit_parse_size (const char *str); +extern NBDKIT_DLLEXPORT int nbdkit_parse_bool (const char *str); +extern NBDKIT_DLLEXPORT int nbdkit_parse_int (const char *what, + const char *str, + int *r); +extern NBDKIT_DLLEXPORT int nbdkit_parse_unsigned (const char *what, + const char *str, + unsigned *r); +extern NBDKIT_DLLEXPORT int nbdkit_parse_int8_t (const char *what, + const char *str, + int8_t *r); +extern NBDKIT_DLLEXPORT int nbdkit_parse_uint8_t (const char *what, + const char *str, + uint8_t *r); +extern NBDKIT_DLLEXPORT int nbdkit_parse_int16_t (const char *what, + const char *str, + int16_t *r); +extern NBDKIT_DLLEXPORT int nbdkit_parse_uint16_t (const char *what, + const char *str, + uint16_t *r); +extern NBDKIT_DLLEXPORT int nbdkit_parse_int32_t (const char *what, + const char *str, + int32_t *r); +extern NBDKIT_DLLEXPORT int nbdkit_parse_uint32_t (const char *what, + const char *str, + uint32_t *r); +extern NBDKIT_DLLEXPORT int nbdkit_parse_int64_t (const char *what, + const char *str, + int64_t *r); +extern NBDKIT_DLLEXPORT int nbdkit_parse_uint64_t (const char *what, + const char *str, + uint64_t *r); +extern NBDKIT_DLLEXPORT int nbdkit_stdio_safe (void); +extern NBDKIT_DLLEXPORT int nbdkit_read_password (const char *value, + char **password); +extern NBDKIT_DLLEXPORT char *nbdkit_realpath (const char *path); +extern NBDKIT_DLLEXPORT int nbdkit_nanosleep (unsigned sec, unsigned nsec); +extern NBDKIT_DLLEXPORT int nbdkit_peer_name (struct sockaddr *addr, + socklen_t *addrlen); +extern NBDKIT_DLLEXPORT void nbdkit_shutdown (void); struct nbdkit_extents; -extern int nbdkit_add_extent (struct nbdkit_extents *, +extern NBDKIT_DLLEXPORT int nbdkit_add_extent (struct nbdkit_extents *, uint64_t offset, uint64_t length, uint32_t type); struct nbdkit_exports; -extern int nbdkit_add_export (struct nbdkit_exports *, +extern NBDKIT_DLLEXPORT int nbdkit_add_export (struct nbdkit_exports *, const char *name, const char *description); /* A static non-NULL pointer which can be used when you don't need a diff --git a/include/nbdkit-filter.h b/include/nbdkit-filter.h index 6aba1aec..bd0d5425 100644 --- a/include/nbdkit-filter.h +++ b/include/nbdkit-filter.h @@ -115,16 +115,24 @@ struct nbdkit_extent { uint32_t type; }; -extern struct nbdkit_extents *nbdkit_extents_new (uint64_t start, uint64_t end); -extern void nbdkit_extents_free (struct nbdkit_extents *); -extern size_t nbdkit_extents_count (const struct nbdkit_extents *); -extern struct nbdkit_extent nbdkit_get_extent (const struct nbdkit_extents *, - size_t); -extern int nbdkit_extents_aligned (struct nbdkit_next_ops *next_ops, - nbdkit_backend *nxdata, - uint32_t count, uint64_t offset, - uint32_t flags, uint32_t align, - struct nbdkit_extents *extents, int *err); +extern NBDKIT_DLLEXPORT +struct nbdkit_extents *nbdkit_extents_new (uint64_t start, uint64_t end); +extern NBDKIT_DLLEXPORT +void nbdkit_extents_free (struct nbdkit_extents *); +extern NBDKIT_DLLEXPORT +size_t nbdkit_extents_count (const struct nbdkit_extents *); +extern NBDKIT_DLLEXPORT +struct nbdkit_extent nbdkit_get_extent (const struct nbdkit_extents *, + size_t); +extern NBDKIT_DLLEXPORT +int nbdkit_extents_aligned (struct nbdkit_next_ops *next_ops, + nbdkit_backend *nxdata, + uint32_t count, + uint64_t offset, + uint32_t flags, + uint32_t align, + struct nbdkit_extents *extents, + int *err); /* Export functions. */ struct nbdkit_export { @@ -132,11 +140,15 @@ struct nbdkit_export { char *description; }; -extern struct nbdkit_exports *nbdkit_exports_new (int default_only); -extern void nbdkit_exports_free (struct nbdkit_exports *); -extern size_t nbdkit_exports_count (const struct nbdkit_exports *); -extern const struct nbdkit_export nbdkit_get_export (const struct nbdkit_exports *, - size_t); +extern NBDKIT_DLLEXPORT +struct nbdkit_exports *nbdkit_exports_new (int default_only); +extern NBDKIT_DLLEXPORT +void nbdkit_exports_free (struct nbdkit_exports *); +extern NBDKIT_DLLEXPORT +size_t nbdkit_exports_count (const struct nbdkit_exports *); +extern NBDKIT_DLLEXPORT +const struct nbdkit_export nbdkit_get_export (const struct nbdkit_exports *, + size_t); /* Filter struct. */ struct nbdkit_filter { diff --git a/include/nbdkit-plugin.h b/include/nbdkit-plugin.h index e20391b8..23b44ef8 100644 --- a/include/nbdkit-plugin.h +++ b/include/nbdkit-plugin.h @@ -144,9 +144,9 @@ struct nbdkit_plugin { struct nbdkit_exports *exports); }; -extern void nbdkit_set_error (int err); -extern const char *nbdkit_export_name (void); -extern int nbdkit_is_tls (void); +extern NBDKIT_DLLEXPORT void nbdkit_set_error (int err); +extern NBDKIT_DLLEXPORT const char *nbdkit_export_name (void); +extern NBDKIT_DLLEXPORT int nbdkit_is_tls (void); #define NBDKIT_REGISTER_PLUGIN(plugin) \ NBDKIT_CXX_LANG_C \ diff --git a/server/main.c b/server/main.c index a96ac88b..f6ffd9b2 100644 --- a/server/main.c +++ b/server/main.c @@ -171,6 +171,8 @@ dump_config (void) #endif } +extern NBDKIT_DLLEXPORT int nbdkit_main (int argc, char *argv[]); + int nbdkit_main (int argc, char *argv[]) { -- 2.27.0
Richard W.M. Jones
2020-Aug-18 10:50 UTC
[Libguestfs] [PATCH nbdkit 9/9] server: Port to Windows.
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 | 10 ++ configure.ac | 23 +++- common/utils/Makefile.am | 31 +++++ 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 | 43 ++++++- 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 | 1 + README | 49 +++++++ TODO | 35 ++++- 23 files changed, 979 insertions(+), 22 deletions(-) diff --git a/include/nbdkit-common.h b/include/nbdkit-common.h index 8684b95a..991bcd22 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> @@ -55,7 +61,11 @@ extern "C" { #define ATTRIBUTE_FORMAT_PRINTF(fmtpos, argpos) #endif +#ifdef WIN32 +#define NBDKIT_DLLEXPORT __declspec(dllexport) +#else #define NBDKIT_DLLEXPORT +#endif #define NBDKIT_THREAD_MODEL_SERIALIZE_CONNECTIONS 0 #define NBDKIT_THREAD_MODEL_SERIALIZE_ALL_REQUESTS 1 diff --git a/configure.ac b/configure.ac index bd9bd65f..5e18ba4a 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]) @@ -468,6 +479,7 @@ AC_MSG_CHECKING([if the target is Windows]) AS_CASE([$host_os], [mingw*|msys*|cygwin*], [ is_windows=yes + LIBS="$LIBS -lmsvcrt -lkernel32 -luser32" NO_UNDEFINED_ON_WINDOWS="-no-undefined" LINK_LIBNBDKIT_ON_WINDOWS='$(top_builddir)/server/libnbdkit.la' ], @@ -478,12 +490,15 @@ AC_SUBST([NO_UNDEFINED_ON_WINDOWS]) AC_SUBST([LINK_LIBNBDKIT_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 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/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 f6ffd9b2..d0becaf1 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 @@ -79,6 +82,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 */ @@ -190,6 +194,7 @@ nbdkit_main (int argc, char *argv[]) const char *magic_config_key; error_if_stdio_closed (); + winsock_init (); #if !ENABLE_LIBFUZZER threadlocal_init (); @@ -730,6 +735,8 @@ nbdkit_main (int argc, char *argv[]) return EXIT_SUCCESS; } +#ifndef WIN32 + /* Implementation of '-U -' */ static char * make_random_fifo (void) @@ -762,6 +769,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) { @@ -1003,6 +1020,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); @@ -1012,6 +1030,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 @@ -1026,6 +1045,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) { @@ -1043,6 +1063,8 @@ switch_stdio (void) exit (EXIT_FAILURE); } } +#endif +#ifndef WIN32 close (STDIN_FILENO); close (STDOUT_FILENO); if (open ("/dev/null", O_RDONLY) != STDIN_FILENO || @@ -1050,4 +1072,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-codes-2 +# 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..3d04f927 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 diff --git a/README b/README index 0e295146..707a8672 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 + 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 ------------------ -- 2.27.0
Eric Blake
2020-Aug-18 12:48 UTC
Re: [Libguestfs] [PATCH nbdkit 1/9] server: Add libnbdkit.so.
On 8/18/20 5:50 AM, Richard W.M. Jones wrote:> This essentially turns the whole of nbdkit into a library. There is a > rump nbdkit program left which simply contains a main() function that > forwards to the nbdkit_main() function in the library. > > The reason for this is to allow nbdkit to be compiled on Windows, > because Windows does not allow shared libraries to contain any > undefined symbols. nbdkit previously relied on undefined symbols in > all plugins and filters (eg. nbdkit_parse_int) which get resolved at > run time by the nbdkit program. In order to make this work on Windows > we need to have a new library (libnbdkit.so on Linux, but probably > called something like LIBNBDKIT.DLL on Windows) which will contain > these symbols, and plugins can then be compiled with -lnbdkit so they > will link with this library, hence no undefined symbols.This is a lot nicer than the last attempt we made several months ago to move only a bare minimum into a library.> > Note this change is backwards compatible. Because the rump nbdkit > binary links with -lnbdkit it still contains and reexports all the > symbols, so plugins and filters which don't explicitly link with > -lnbdkit will still be loadable (on existing platforms). > --- > server/Makefile.am | 21 ++++++++------ > server/main.c | 2 +- > server/nbdkit.c | 46 ++++++++++++++++++++++++++++++ > server/nbdkit.syms | 1 + > tests/test-nbdkit-backend-debug.sh | 24 ++++++++-------- > wrapper.c | 10 +++++-- > 6 files changed, 80 insertions(+), 24 deletions(-)ACK.> -nbdkit_LDFLAGS = \ > +libnbdkit_la_LDFLAGS = \ > + -shared $(NO_UNDEFINED_ON_WINDOWS) \On first read, I didn't see where this was declared; but then I saw you have already pushed some preliminary cleanups, including adding NO_UNDEFINED_ON_WINDOWS in 9d052c1d.> +++ b/server/nbdkit.c> +#include <config.h> > + > +#include <stdio.h> > + > +extern int nbdkit_main (int argc, char *argv[]);A bit odd to declare this in a .c; but I don't see any existing decent .h to put it in, nor is it worth adding a new one just for this. So it is fine right here.> + > +int > +main (int argc, char *argv[]) > +{ > + /* This does nothing except call into the real main function in > + * libnbdkit.so. > + */ > + return nbdkit_main (argc, argv); > +} > diff --git a/server/nbdkit.syms b/server/nbdkit.syms > index a67669b7..a516cc0f 100644 > --- a/server/nbdkit.syms > +++ b/server/nbdkit.syms > @@ -54,6 +54,7 @@ > nbdkit_extents_new; > nbdkit_get_extent; > nbdkit_is_tls; > + nbdkit_main;Do we want to export it as _nbdkit_main, to make it obvious that plugins shouldn't try calling it? That's cosmetic if you think it is worth it. -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3226 Virtualization: qemu.org | libvirt.org
Eric Blake
2020-Aug-18 12:57 UTC
Re: [Libguestfs] [PATCH nbdkit 2/9] build: On Windows only, link all plugins and filters with -lnbdkit.
On 8/18/20 5:50 AM, Richard W.M. Jones wrote:> ---> +++ b/configure.ac > @@ -457,11 +457,13 @@ AS_CASE([$host_os], > [mingw*|msys*|cygwin*], [ > is_windows=yes > NO_UNDEFINED_ON_WINDOWS="-no-undefined" > + LINK_LIBNBDKIT_ON_WINDOWS='$(top_builddir)/server/libnbdkit.la'Cygwin supports linking with undefined symbols, but it does add some redirection overhead, so I don't see a problem in including Cygwin with native windows for this case. But we may need to later distinguish between Cygwin and native windows for other parts of the porting efforts. For now, I'm fine with this patch.> +++ 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 \ > + $(LINK_LIBNBDKIT_ON_WINDOWS) \ > + $(EXT2FS_LIBS) $(COM_ERR_LIBS) \The reordering is a bit unrelated, but a nice cleanup.> +++ 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 \ > + $(LINK_LIBNBDKIT_ON_WINDOWS) \ > + $(CURL_LIBS) \and another one. I see a few more as well (guestfs, python, ssh, torrent)> +++ b/plugins/tcl/Makefile.am > @@ -52,10 +52,13 @@ nbdkit_tcl_plugin_la_CFLAGS = \ > $(WARNINGS_CFLAGS) \ > $(TCL_CFLAGS) \ > $(NULL) > +nbdkit_tcl_plugin_la_LIBADD = \ > + $(LINK_LIBNBDKIT_ON_WINDOWS) \ > + $(TCL_LIBS) \ > + $(NULL) > nbdkit_tcl_plugin_la_LDFLAGS = \ > -module -avoid-version -shared $(NO_UNDEFINED_ON_WINDOWS) \ > -Wl,--version-script=$(top_srcdir)/plugins/plugins.syms \ > - $(TCL_LIBS) \ > $(NULL)And this one's a good fix (LIBADD affects a different part of the command line than LDFLAGS). Is it worth calling out these additional cleanups as intentional as part of the commit message? ACK -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3226 Virtualization: qemu.org | libvirt.org
Eric Blake
2020-Aug-18 13:20 UTC
Re: [Libguestfs] [PATCH nbdkit 3/9] server: Add general replacements for missing functions using LIBOBJS.
On 8/18/20 5:50 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 written by me > > This should do nothing on existing supported platforms. It is only > intended in preparation for porting nbdkit to Windows. > ---> @@ -464,6 +475,15 @@ AS_CASE([$host_os], > AC_MSG_RESULT([$is_windows]) > AC_SUBST([NO_UNDEFINED_ON_WINDOWS]) > AC_SUBST([LINK_LIBNBDKIT_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])]) > +])That's true for native windows, but not for cygwin. This one looks like our grouping of Cygwin as being 'is_windows' will bite us.> +++ b/common/replacements/Makefile.am > @@ -0,0 +1,53 @@ > +# nbdkit > +# Copyright (C) 2019 Red Hat Inc.You can add 2020 if desired.> +++ b/common/replacements/win32/Makefile.am > @@ -0,0 +1,46 @@ > +# nbdkit > +# Copyright (C) 2019 Red Hat Inc.and again> +# All rights reserved.Stale copy-and-paste; we got rid of these lines in 1.12.> +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) $<Is the message catalog integral to the general function replacements, or should this be split into a separate commit?> +++ b/common/replacements/getline.h > @@ -0,0 +1,50 @@ > +/* nbdkit > + * Copyright (C) 2019 Red Hat Inc. > + * All rights reserved.More of this line; looks like you'll want to scrub the series.> + > +#ifndef NBDKIT_GETLINE_H > +#define NBDKIT_GETLINE_H > + > +#include <config.h> > + > +#ifdef HAVE_GETLINE > + > +#include <stdio.h>You'll want this include to be unconditional, since...> + > +#else > + > +ssize_t getline (char **lineptr, size_t *n, FILE *stream);the reference to ssize_t and FILE* depend on it.> +++ b/common/replacements/realpath.h> + > +#include <config.h> > + > +#ifdef HAVE_REALPATH > + > +#include <limits.h> > +#include <stdlib.h>Why limits.h?> + > +#else > + > +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..464ce954 > --- /dev/null > +++ b/common/replacements/strndup.h> +#ifndef NBDKIT_STRNDUP_H > +#define NBDKIT_STRNDUP_H > + > +#include <config.h> > + > +#ifdef HAVE_STRNDUP > + > +#include <string.h> > + > +#else > + > +char *strndup(const char *s, size_t n);You'll probably want a header to guarantee size_t is defined (either stddef.h or sys/types.h works).> + > +#endif > + > +#endif /* NBDKIT_STRNDUP_H */ > diff --git a/common/replacements/syslog.h b/common/replacements/syslog.h > new file mode 100644 > index 00000000..e4d76677 > --- /dev/null > +++ b/common/replacements/syslog.h> +#include <config.h> > + > +#ifdef HAVE_SYSLOG_H > + > +#include_next <syslog.h>I guess our insistence on a decent compiler (for other reasons such as __attribute__((cleanup))) means we can rely on #include_next ;)> +++ 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 one makes sense; you are lifting it straight out of another source verbatim.> +++ b/common/replacements/openlog.c> +#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); > +}Ah, so if I understand, the message catalog compilation matters when replacing openlog? Cygwin has openlog, and thus does not need the replacement and thus not the message catalog.> + > +#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..622ee7ea > --- /dev/null > +++ b/common/replacements/realpath.c> +++ b/common/replacements/strndup.c> + > +char * > +strndup(const char *s, size_t n) > +{ > + size_t len = strlen (s);You _must_ use strnlen here. Otherwise, a user that passes in a pointer to bytes that are bounded by a memory page transition rather than a NUL can cause you to SEGV reading beyond n bytes.> + char *ret; > + > + if (len > n) > + len = n;and once you've used strnlen, this is dead.> + > + ret = malloc (len+1); > + if (ret == NULL) > + return NULL; > + memcpy (ret, s, len); > + ret[len] = '\0'; > + > + return ret; > +} > + > +#endif /* !HAVE_STRNDUP */ > diff --git a/common/replacements/syslog.c b/common/replacements/syslog.c > new file mode 100644 > index 00000000..6f41cbd8 > --- /dev/null > +++ b/common/replacements/syslog.c> +++ b/common/replacements/vsyslog.c> +++ b/common/replacements/win32/nbdkit-cat.mc > @@ -0,0 +1,6 @@ > +MessageId=1 > +Severity=Error > +SymbolicName=NBDKIT_SYSLOG_ERROR > +Language=English > +%1 > +.Does this file not allow for a copyright blurb? Or is it small enough to be trivial and not need one? -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3226 Virtualization: qemu.org | libvirt.org
Eric Blake
2020-Aug-18 13:24 UTC
Re: [Libguestfs] [PATCH nbdkit 6/9] lib: Use replacement strategy for get_current_dir_name.
On 8/18/20 5:50 AM, Richard W.M. Jones wrote:> 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 | 10 ++++ > plugins/floppy/Makefile.am | 1 + > common/replacements/get_current_dir_name.h | 49 +++++++++++++++++++ > 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, 69 insertions(+), 17 deletions(-)ACK 4-6. Reminds me of an unrelated question - when a user writes: nbdkit memory --run './command' rather than nbdkit memory --run '/path/to/command' do we guarantee that the --run snippet will use the current working directory that nbdkit started under, even though nbdkit itself chdir's away to / as part of starting the plugin? (If we do guarantee it, do we test it? If we haven't yet guaranteed it, should we?)> +++ b/common/replacements/get_current_dir_name.h > @@ -0,0 +1,49 @@ > +/* nbdkit > + * Copyright (C) 2018 Red Hat Inc. > + * All rights reserved.2020, lose 'All rights reserved'... -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3226 Virtualization: qemu.org | libvirt.org
Eric Blake
2020-Aug-18 13:31 UTC
Re: [Libguestfs] [PATCH nbdkit 7/9] server: Add hand-written replacement for poll for Windows.
On 8/18/20 5:50 AM, Richard W.M. Jones wrote:> --- > 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 | 106 ++++++++++++++++++++++++++++++++ > 6 files changed, 171 insertions(+), 2 deletions(-)My native windows coding is weak, so take this review with a grain of salt.> +++ b/common/replacements/poll.c> +#ifndef HAVE_POLL > + > +#include "poll.h" > + > +#ifdef WIN32 > + > +#include <winsock2.h> > +#include <ws2tcpip.h> > +#include <windows.h> > + > +/* Windows doesn't have poll. It has something called WSAPoll in > + * Winsock, but even MSFT admit it is broken. Gnulib contains anIs MSFT considered plural, or should that be 'admits'> + * elaborate emulation of poll written by Paolo, but it's distributedI know who you mean, but is it worth a surname?> + * 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, nfds = 0, r; > + fd_set readfds, writefds; > + struct timeval tv, *tvp; > + > + 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); > + if (fds[i].fd > nfds) > + nfds = fds[i].fd; > + fds[i].revents = 0; > + } > + nfds++;Do we need to make sure that nfds does not exceed the limits of select? Calling FD_SET on a too-large fd causes memory corruption (twiddling bits outside of the fixed-length bitset is never good). Offhand, I didn't know the windows bitset length, but a quick google found: https://docs.microsoft.com/en-us/windows/win32/winsock/maximum-number-of-sockets-supported-2 where the default limit is 64 unless you set a compile-time macro prior to winsock2.h. -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3226 Virtualization: qemu.org | libvirt.org
Eric Blake
2020-Aug-18 13:33 UTC
Re: [Libguestfs] [PATCH nbdkit 8/9] include: Prefix all exports with NBDKIT_DLLEXPORT.
On 8/18/20 5:50 AM, Richard W.M. Jones wrote:> This is #defined as empty at the moment, but it allows the Windows > port to define this __declspec(dllexport), which is necessary for > symbols to be exported in DLLs. > --- > include/nbdkit-common.h | 86 ++++++++++++++++++++++++----------------- > include/nbdkit-filter.h | 42 +++++++++++++------- > include/nbdkit-plugin.h | 6 +-- > server/main.c | 2 + > 4 files changed, 83 insertions(+), 53 deletions(-)ACK.> +extern NBDKIT_DLLEXPORT int nbdkit_parse_unsigned (const char *what, > + const char *str, > + unsigned *r);This leads to some awkward-looking hanging. Should we reformat differently, similar to: extern NBDKIT_DLLEXPORT int nbdkit_parse_unsigned (const char *what, const char *str, unsigned *r); ? -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3226 Virtualization: qemu.org | libvirt.org
Apparently Analagous Threads
- [PATCH nbdkit 3/9] server: Add general replacements for missing functions using LIBOBJS.
- [PATCH nbdkit 01/13] common/replacements: Replace missing functions using LIBOBJS.
- Re: [PATCH nbdkit 01/13] common/replacements: Replace missing functions using LIBOBJS.
- [PATCH nbdkit 0/9] Port to Windows.
- [PATCH nbdkit incomplete 0/5] Port to Windows.