From patchwork Fri Mar 11 10:03:51 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= X-Patchwork-Id: 8563981 Return-Path: X-Original-To: patchwork-qemu-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id D9647C0553 for ; Fri, 11 Mar 2016 10:06:53 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 7DA1A20361 for ; Fri, 11 Mar 2016 10:06:52 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7962E20328 for ; Fri, 11 Mar 2016 10:06:51 +0000 (UTC) Received: from localhost ([::1]:53808 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aeJy6-0007Ku-GP for patchwork-qemu-devel@patchwork.kernel.org; Fri, 11 Mar 2016 05:06:50 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:51955) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aeJvn-0003dc-Dk for qemu-devel@nongnu.org; Fri, 11 Mar 2016 05:04:31 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aeJvj-0001ey-Ck for qemu-devel@nongnu.org; Fri, 11 Mar 2016 05:04:27 -0500 Received: from mx1.redhat.com ([209.132.183.28]:35588) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aeJvj-0001es-5F for qemu-devel@nongnu.org; Fri, 11 Mar 2016 05:04:23 -0500 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (Postfix) with ESMTPS id C6C107EBB8; Fri, 11 Mar 2016 10:04:22 +0000 (UTC) Received: from t530wlan.home.berrange.com.com (vpn1-6-25.ams2.redhat.com [10.36.6.25]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u2BA4Kqe022231; Fri, 11 Mar 2016 05:04:21 -0500 From: "Daniel P. Berrange" To: qemu-devel@nongnu.org Date: Fri, 11 Mar 2016 10:03:51 +0000 Message-Id: <1457690648-19267-2-git-send-email-berrange@redhat.com> In-Reply-To: <1457690648-19267-1-git-send-email-berrange@redhat.com> References: <1457690648-19267-1-git-send-email-berrange@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: Peter Maydell Subject: [Qemu-devel] [PULL v1 01/18] osdep: fix socket_error() to work with Mingw64 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 Exxxx 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 WSAExxxx errno values in winerror.h do not match the Exxxx 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 WSAExxxx 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 WSAExxxx constant values match the Exxx constant values. Thus the socket_error() macro is turned into a small function that re-maps WSAExxxx values into Exxx. Reviewed-by: Paolo Bonzini Signed-off-by: Daniel P. Berrange --- include/qemu/sockets.h | 3 -- include/sysemu/os-posix.h | 2 ++ include/sysemu/os-win32.h | 27 +--------------- util/oslib-win32.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 81 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 EINTR WSAEINTR -#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..1f717ee 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,83 @@ int socket_set_fast_reuse(int fd) return 0; } + +int socket_error(void) +{ + switch (WSAGetLastError()) { + case 0: + return 0; + case WSAEINTR: + return EINTR; + case WSAEINVAL: + return EINVAL; + 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: + /* not using EWOULDBLOCK as we don't want code to have + * to check both EWOULDBLOCK and EAGAIN */ + return EAGAIN; + 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 ENOPROTOOPT; + case WSAEPROTONOSUPPORT: + return EPROTONOSUPPORT; + case WSAEOPNOTSUPP: + return EOPNOTSUPP; + case WSAEAFNOSUPPORT: + return EAFNOSUPPORT; + case WSAEADDRINUSE: + return EADDRINUSE; + case WSAEADDRNOTAVAIL: + return EADDRNOTAVAIL; + case WSAENETDOWN: + return ENETDOWN; + case WSAENETUNREACH: + return ENETUNREACH; + case WSAENETRESET: + return ENETRESET; + case WSAECONNABORTED: + return ECONNABORTED; + case WSAECONNRESET: + return ECONNRESET; + case WSAENOBUFS: + return ENOBUFS; + case WSAEISCONN: + return EISCONN; + case WSAENOTCONN: + return ENOTCONN; + case WSAETIMEDOUT: + return ETIMEDOUT; + case WSAECONNREFUSED: + return ECONNREFUSED; + case WSAELOOP: + return ELOOP; + case WSAEHOSTUNREACH: + return EHOSTUNREACH; + default: + return EIO; + } +} + int inet_aton(const char *cp, struct in_addr *ia) { uint32_t addr = inet_addr(cp);