[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[Libvir] [PATCH] A few more Windows / MinGW fixups



A few fairly miscellaneous fixups for Windows (MinGW) which fix shared library builds and fix error handling for sockets.

(1) XDR functions on MinGW come from a library called 'libxdr', not 'librpc'.

(2) To build a DLL under MinGW we need to pass the -no-undefined flag to the linker.

(3) Socket compatibility header file replaces <winsock2.h> inclusion. This just defines a portable 'socket_errno()' function which returns errno in the normal case, or WSAGetLastError() in the Windows case.

(4) Use socket_errno() instead of errno in a few cases (but only when the code can be compiled under Windows, ie. only in the remote client case).

Example -- a dynamically linked virsh.exe (linked to libvirt-0.dll) accessing a remote libvirtd:

$ src/.libs/virsh.exe -c test+tcp://192.168.2.128/default list
 Id Name                 State
----------------------------------
  1 test                 running

If you want to compile this under Windows, you will need:

(a) MinGW & MSYS (select the "candidate" versions of MinGW tools if you are using Vista or W2K8, since otherwise nothing works because of a known bug).

(b) Install gcc 4 experimental package from MinGW site. It's called gcc-sjlj for reasons which escape me.

(c) Install GnuTLS binary from http://www.gnu.org/software/gnutls/download.html. I'm using GnuTLS Windows binary 1.6.3 and I had to hand-hack the *.la files in that distribution because they contain incorrect paths.

(d) Compile and install latest libxml2 from http://xmlsoft.org/. I'm using 2.6.30.

(e) Compile and install my XDR package for Windows (http://www.annexia.org/tmp/xdr-4.0-mingw5.tar.gz)

(f) ./configure --without-xen --without-qemu --without-sasl --without-libvirtd

(g) make

Rich.

--
Emerging Technologies, Red Hat - http://et.redhat.com/~rjones/
Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod
Street, Windsor, Berkshire, SL4 1TE, United Kingdom.  Registered in
England and Wales under Company Registration No. 03798903
Index: configure.in
===================================================================
RCS file: /data/cvs/libvirt/configure.in,v
retrieving revision 1.116
diff -u -r1.116 configure.in
--- configure.in	17 Dec 2007 23:20:13 -0000	1.116
+++ configure.in	4 Jan 2008 12:44:36 -0000
@@ -65,8 +65,8 @@
 dnl Availability of various common headers (non-fatal if missing).
 AC_CHECK_HEADERS([pwd.h paths.h sys/syslimits.h sys/utsname.h sys/wait.h winsock2.h])
 
-dnl Need -lrpc? (Cygwin needs this)
-AC_SEARCH_LIBS(xdrmem_create,rpc)
+dnl Need -lrpc or -lxdr? (Cygwin and MinGW resp. need this)
+AC_SEARCH_LIBS(xdrmem_create,[rpc xdr])
 
 dnl Do we have rpcgen?
 AC_PATH_PROG(RPCGEN, rpcgen, no)
@@ -650,6 +650,7 @@
 CYGWIN_EXTRA_LDFLAGS=
 CYGWIN_EXTRA_LIBADD=
 CYGWIN_EXTRA_PYTHON_LIBADD=
+MINGW_EXTRA_LDFLAGS=
 case "$host" in
   *-*-cygwin*)
     CYGWIN_EXTRA_LDFLAGS="-no-undefined"
@@ -658,10 +659,14 @@
       CYGWIN_EXTRA_PYTHON_LIBADD="-L/usr/lib/python${PYTHON_VERSION}/config -lpython${PYTHON_VERSION}"
     fi
     ;;
+  *-*-mingw*)
+    MINGW_EXTRA_LDFLAGS="-no-undefined"
+    ;;
 esac
 AC_SUBST(CYGWIN_EXTRA_LDFLAGS)
 AC_SUBST(CYGWIN_EXTRA_LIBADD)
 AC_SUBST(CYGWIN_EXTRA_PYTHON_LIBADD)
+AC_SUBST(MINGW_EXTRA_LDFLAGS)
 
 # very annoying
 rm -f COPYING
Index: gnulib/lib/arpa/.cvsignore
===================================================================
RCS file: /data/cvs/libvirt/gnulib/lib/arpa/.cvsignore,v
retrieving revision 1.1
diff -u -r1.1 .cvsignore
--- gnulib/lib/arpa/.cvsignore	7 Dec 2007 14:32:35 -0000	1.1
+++ gnulib/lib/arpa/.cvsignore	4 Jan 2008 12:44:36 -0000
@@ -0,0 +1 @@
+inet.h
Index: src/Makefile.am
===================================================================
RCS file: /data/cvs/libvirt/src/Makefile.am,v
retrieving revision 1.61
diff -u -r1.61 Makefile.am
--- src/Makefile.am	17 Dec 2007 10:07:56 -0000	1.61
+++ src/Makefile.am	4 Jan 2008 12:44:37 -0000
@@ -31,6 +31,7 @@
 CLIENT_SOURCES =						\
 		libvirt.c internal.h				\
 		gnutls_1_0_compat.h				\
+		socketcompat.h					\
 		hash.c hash.h					\
 		test.c test.h                                   \
                 buf.c buf.h					\
@@ -68,7 +69,7 @@
 libvirt_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libvirt_sym.version \
                      -version-info @LIBVIRT_VERSION_INFO@ \
                     $(COVERAGE_CFLAGS:-f%=-Wc,-f%) \
-		    @CYGWIN_EXTRA_LDFLAGS@
+		    @CYGWIN_EXTRA_LDFLAGS@ @MINGW_EXTRA_LDFLAGS@
 libvirt_la_CFLAGS = $(COVERAGE_CFLAGS)
 
 bin_PROGRAMS = virsh
Index: src/libvirt.c
===================================================================
RCS file: /data/cvs/libvirt/src/libvirt.c,v
retrieving revision 1.110
diff -u -r1.110 libvirt.c
--- src/libvirt.c	15 Dec 2007 17:15:12 -0000	1.110
+++ src/libvirt.c	4 Jan 2008 12:44:39 -0000
@@ -25,7 +25,7 @@
 #include <libxml/uri.h>
 #include "getpass.h"
 
-#if HAVE_WINSOCK2_H
+#ifdef HAVE_WINSOCK2_H
 #include <winsock2.h>
 #endif
 
Index: src/qparams.c
===================================================================
RCS file: /data/cvs/libvirt/src/qparams.c,v
retrieving revision 1.1
diff -u -r1.1 qparams.c
--- src/qparams.c	17 Dec 2007 10:07:56 -0000	1.1
+++ src/qparams.c	4 Jan 2008 12:44:39 -0000
@@ -20,6 +20,8 @@
  * Utility functions to help parse and assemble query strings.
  */
 
+#include <config.h>
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdarg.h>
Index: src/remote_internal.c
===================================================================
RCS file: /data/cvs/libvirt/src/remote_internal.c,v
retrieving revision 1.50
diff -u -r1.50 remote_internal.c
--- src/remote_internal.c	2 Jan 2008 22:48:04 -0000	1.50
+++ src/remote_internal.c	4 Jan 2008 12:44:42 -0000
@@ -23,12 +23,14 @@
 
 #include "config.h"
 
+/* Windows socket compatibility functions. */
+#include "socketcompat.h"
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <string.h>
 #include <assert.h>
-#include <errno.h>
 #include <signal.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -46,15 +48,6 @@
 #include <paths.h>
 #endif
 
-#ifndef HAVE_WINSOCK2_H
-#include <sys/socket.h>
-#include <netdb.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#else
-#include <winsock2.h>
-#endif
-
 #include <rpc/types.h>
 #include <rpc/xdr.h>
 #include <gnutls/gnutls.h>
@@ -525,7 +518,7 @@
 
             priv->sock = socket (r->ai_family, SOCK_STREAM, 0);
             if (priv->sock == -1) {
-                error (conn, VIR_ERR_SYSTEM_ERROR, strerror (errno));
+                error (conn, VIR_ERR_SYSTEM_ERROR, strerror (socket_errno ()));
                 continue;
             }
 
@@ -535,7 +528,7 @@
                         sizeof no_slow_start);
 
             if (connect (priv->sock, r->ai_addr, r->ai_addrlen) == -1) {
-                error (conn, VIR_ERR_SYSTEM_ERROR, strerror (errno));
+                error (conn, VIR_ERR_SYSTEM_ERROR, strerror (socket_errno ()));
                 close (priv->sock);
                 continue;
             }
@@ -3036,7 +3029,7 @@
         __virRaiseError (in_open ? NULL : conn, NULL, NULL, VIR_FROM_REMOTE,
                          VIR_ERR_AUTH_FAILED, VIR_ERR_ERROR, NULL, NULL, NULL, 0, 0,
                          "failed to get sock address %d (%s)",
-                         errno, strerror(errno));
+                         socket_errno (), strerror(socket_errno ()));
         goto cleanup;
     }
     if ((localAddr = addrToString(&sa, salen)) == NULL)
@@ -3048,7 +3041,7 @@
         __virRaiseError (in_open ? NULL : conn, NULL, NULL, VIR_FROM_REMOTE,
                          VIR_ERR_AUTH_FAILED, VIR_ERR_ERROR, NULL, NULL, NULL, 0, 0,
                          "failed to get peer address %d (%s)",
-                         errno, strerror(errno));
+                         socket_errno (), strerror(socket_errno ()));
         goto cleanup;
     }
     if ((remoteAddr = addrToString(&sa, salen)) == NULL)
@@ -3601,12 +3594,13 @@
         while (len > 0);
     } else {
         do {
-            err = write (priv->sock, p, len);
+            err = send (priv->sock, p, len, 0);
             if (err == -1) {
-                if (errno == EINTR || errno == EAGAIN)
+                int errno_ = socket_errno ();
+                if (errno_ == EINTR || errno_ == EAGAIN)
                     continue;
                 error (in_open ? NULL : conn,
-                       VIR_ERR_SYSTEM_ERROR, strerror (errno));
+                       VIR_ERR_SYSTEM_ERROR, strerror (errno_));
                 return -1;
             }
             len -= err;
@@ -3683,12 +3677,13 @@
         return err;
     } else {
     reread:
-        err = read (priv->sock, bytes, len);
+        err = recv (priv->sock, bytes, len, 0);
         if (err == -1) {
-            if (errno == EINTR)
+            int errno_ = socket_errno ();
+            if (errno_ == EINTR)
                 goto reread;
             error (in_open ? NULL : conn,
-                   VIR_ERR_SYSTEM_ERROR, strerror (errno));
+                   VIR_ERR_SYSTEM_ERROR, strerror (errno_));
             return -1;
         }
         if (err == 0) {
Index: src/socketcompat.h
===================================================================
RCS file: src/socketcompat.h
diff -N src/socketcompat.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ src/socketcompat.h	4 Jan 2008 12:44:42 -0000
@@ -0,0 +1,60 @@
+/*
+ * socketcompat.h: Socket compatibility for Windows, making it slightly
+ * less painful to use.
+ *
+ * Use this header under the following circumstances:
+ * (a) Instead of including any of: <net/if.h>, <netinet/in.h>,
+ *     <sys/socket.h>, <netdb.h>, <netinet/tcp.h>, AND
+ * (b) The file will be part of what is built on Windows (basically
+ *     just remote client stuff).
+ *
+ * You need to use socket_errno() instead of errno to get socket
+ * errors.
+ *
+ * Copyright (C) 2008 Red Hat, Inc.
+ *
+ * See COPYING.LIB for the License of this software
+ *
+ * Richard W.M. Jones <rjones redhat com>
+ */
+
+#ifndef __SOCKETCOMPAT_H__
+#define __SOCKETCOMPAT_H__
+
+#include <config.h>
+
+#include <errno.h>
+
+#ifndef HAVE_WINSOCK2_H		/* Unix & Cygwin. */
+
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+
+static inline int
+socket_errno (void)
+{
+  return errno;
+}
+
+#else                           /* MinGW & Win32 */
+
+#include <winsock2.h>
+
+/* Socket functions in Windoze don't set errno.  Instead of using errno
+ * to test for socket errors, call this function to get the errno.
+ */
+static inline int
+socket_errno (void)
+{
+  return WSAGetLastError ();
+}
+
+/* Compatibility. */
+#define EWOULDBLOCK             WSAEWOULDBLOCK
+#define ECONNREFUSED            WSAECONNREFUSED
+
+#endif /* HAVE_WINSOCK2_H */
+
+#endif /* __WINSOCKWRAPPER_H__ */
Index: src/test.c
===================================================================
RCS file: /data/cvs/libvirt/src/test.c,v
retrieving revision 1.56
diff -u -r1.56 test.c
--- src/test.c	11 Dec 2007 21:57:29 -0000	1.56
+++ src/test.c	4 Jan 2008 12:44:43 -0000
@@ -28,7 +28,6 @@
 #include <stdio.h>
 #include <string.h>
 #include <sys/time.h>
-#include <errno.h>
 #include <libxml/parser.h>
 #include <libxml/tree.h>
 #include <libxml/xpath.h>
@@ -37,12 +36,7 @@
 #include <unistd.h>
 #include <sys/stat.h>
 
-#ifndef HAVE_WINSOCK2_H
-#include <net/if.h>
-#include <netinet/in.h>
-#else
-#include <winsock2.h>
-#endif
+#include "socketcompat.h"
 
 #include "internal.h"
 #include "test.h"

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]