Re: [Qemu-devel] [PATCH] win32: fix socket_error() to work with Mingw64

2016-03-07 Thread Andrew Baumann
> From: Daniel P. Berrange [mailto:berra...@redhat.com]
> Sent: Monday, 7 March 2016 3:29 AM
> 
> Historically QEMU has had a socket_error() macro that was
> defined to map to WSASocketError(). The os-win32.h header
> file would define errno constants that mapped to the
> WSA error constants. This worked fine with Mingw32 since
> its header files never defined any errno values, nor did
> it even provide an errno.h.  So callers of socket_error()
> could match on traditional E constants and it would
> all "just work".
> 
> With Mingw64 though, things work rather differently. First
> there is an errno.h file which defines all the traditional
> errno constants you'd expect from a UNIX platform. There
> is then a winerror.h which defined the WSA error constants.
> Crucially the WSAE errno values in winerror.h do not
> match the E errno values in error.h.
> 
> If QEMU had only imported winerror.h it would still work,
> but the qemu/osdep.h file unconditionally imports errno.h.
> So callers of socket_error() will get now WSAE values
> back and compare them to the Exxx constants. This will
> always fail silently at runtime.
> 
> To solve this QEMU needs to stop assuming the WSAE
> constant values match the Exxx constant values. Thus the
> socket_error() macro is turned into a small function that
> re-maps WSAE values into Exxx.
> 
> Signed-off-by: Daniel P. Berrange 
> ---
> 
> NB, I've not actually done anything other that compile
> test this so far. I'll be doing a runtime test once I
> get my windows VM working with QEMU builds agian...

If it helps, this works for me.

Tested-by: Andrew Baumann 

(It doesn't fix the watch/accept problem, obviously, but at least we can listen 
now.)

Thanks,
Andrew



[Qemu-devel] [PATCH] win32: fix socket_error() to work with Mingw64

2016-03-07 Thread Daniel P. Berrange
Historically QEMU has had a socket_error() macro that was
defined to map to WSASocketError(). The os-win32.h header
file would define errno constants that mapped to the
WSA error constants. This worked fine with Mingw32 since
its header files never defined any errno values, nor did
it even provide an errno.h.  So callers of socket_error()
could match on traditional E constants and it would
all "just work".

With Mingw64 though, things work rather differently. First
there is an errno.h file which defines all the traditional
errno constants you'd expect from a UNIX platform. There
is then a winerror.h which defined the WSA error constants.
Crucially the WSAE errno values in winerror.h do not
match the E errno values in error.h.

If QEMU had only imported winerror.h it would still work,
but the qemu/osdep.h file unconditionally imports errno.h.
So callers of socket_error() will get now WSAE values
back and compare them to the Exxx constants. This will
always fail silently at runtime.

To solve this QEMU needs to stop assuming the WSAE
constant values match the Exxx constant values. Thus the
socket_error() macro is turned into a small function that
re-maps WSAE values into Exxx.

Signed-off-by: Daniel P. Berrange 
---

NB, I've not actually done anything other that compile
test this so far. I'll be doing a runtime test once I
get my windows VM working with QEMU builds agian...

 include/qemu/sockets.h|  3 --
 include/sysemu/os-posix.h |  2 ++
 include/sysemu/os-win32.h | 27 +-
 util/oslib-win32.c| 71 ++-
 4 files changed, 73 insertions(+), 30 deletions(-)

diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h
index 0be68de..49499f2 100644
--- a/include/qemu/sockets.h
+++ b/include/qemu/sockets.h
@@ -7,8 +7,6 @@
 #include 
 #include 
 
-#define socket_error() WSAGetLastError()
-
 int inet_aton(const char *cp, struct in_addr *ia);
 
 #else
@@ -20,7 +18,6 @@ int inet_aton(const char *cp, struct in_addr *ia);
 #include 
 #include 
 
-#define socket_error() errno
 #define closesocket(s) close(s)
 
 #endif /* !_WIN32 */
diff --git a/include/sysemu/os-posix.h b/include/sysemu/os-posix.h
index 5b9c4d6..e9fec2e 100644
--- a/include/sysemu/os-posix.h
+++ b/include/sysemu/os-posix.h
@@ -34,6 +34,8 @@ void os_daemonize(void);
 void os_setup_post(void);
 int os_mlock(void);
 
+#define socket_error() errno
+
 typedef struct timeval qemu_timeval;
 #define qemu_gettimeofday(tp) gettimeofday(tp, NULL)
 
diff --git a/include/sysemu/os-win32.h b/include/sysemu/os-win32.h
index fbed346..239771d 100644
--- a/include/sysemu/os-win32.h
+++ b/include/sysemu/os-win32.h
@@ -29,32 +29,6 @@
 #include 
 #include 
 
-/* Workaround for older versions of MinGW. */
-#ifndef ECONNREFUSED
-# define ECONNREFUSED WSAECONNREFUSED
-#endif
-#ifndef EINPROGRESS
-# define EINPROGRESS  WSAEINPROGRESS
-#endif
-#ifndef EHOSTUNREACH
-# define EHOSTUNREACH WSAEHOSTUNREACH
-#endif
-#ifndef EINTR
-# define EINTRWSAEINTR
-#endif
-#ifndef EINPROGRESS
-# define EINPROGRESS  WSAEINPROGRESS
-#endif
-#ifndef ENETUNREACH
-# define ENETUNREACH  WSAENETUNREACH
-#endif
-#ifndef ENOTCONN
-# define ENOTCONN WSAENOTCONN
-#endif
-#ifndef EWOULDBLOCK
-# define EWOULDBLOCK  WSAEWOULDBLOCK
-#endif
-
 #if defined(_WIN64)
 /* On w64, setjmp is implemented by _setjmp which needs a second parameter.
  * If this parameter is NULL, longjump does no stack unwinding.
@@ -80,6 +54,7 @@ struct tm *gmtime_r(const time_t *timep, struct tm *result);
 struct tm *localtime_r(const time_t *timep, struct tm *result);
 #endif /* CONFIG_LOCALTIME_R */
 
+int socket_error(void);
 
 static inline void os_setup_signal_handling(void) {}
 static inline void os_daemonize(void) {}
diff --git a/util/oslib-win32.c b/util/oslib-win32.c
index 438cfa4..aefada9 100644
--- a/util/oslib-win32.c
+++ b/util/oslib-win32.c
@@ -2,7 +2,7 @@
  * os-win32.c
  *
  * Copyright (c) 2003-2008 Fabrice Bellard
- * Copyright (c) 2010 Red Hat, Inc.
+ * Copyright (c) 2010-2016 Red Hat, Inc.
  *
  * QEMU library functions for win32 which are shared between QEMU and
  * the QEMU tools.
@@ -144,6 +144,75 @@ int socket_set_fast_reuse(int fd)
 return 0;
 }
 
+
+int socket_error(void)
+{
+switch (WSAGetLastError()) {
+case WSA_INVALID_HANDLE:
+return EBADF;
+case WSA_NOT_ENOUGH_MEMORY:
+return ENOMEM;
+case WSA_INVALID_PARAMETER:
+return EINVAL;
+case WSAENAMETOOLONG:
+return ENAMETOOLONG;
+case WSAENOTEMPTY:
+return ENOTEMPTY;
+case WSAEWOULDBLOCK:
+return EWOULDBLOCK;
+case WSAEINPROGRESS:
+return EINPROGRESS;
+case WSAEALREADY:
+return EALREADY;
+case WSAENOTSOCK:
+return ENOTSOCK;
+case WSAEDESTADDRREQ:
+return EDESTADDRREQ;
+case WSAEMSGSIZE:
+return EMSGSIZE;
+case WSAEPROTOTYPE:
+return EPROTOTYPE;
+case WSAENOPROTOOPT:
+return