From 4f79e9b1610788006c48772dfecc571fc1e1a7ac Mon Sep 17 00:00:00 2001 From: Steve Hay Date: Thu, 17 Oct 2013 13:29:28 +0100 Subject: [PATCH] Fix Win32 build with MinGW/gcc-4.8+ which define some errno.h values >= 100 Commit ea95436966 made changes to how errno.h constants are handled for VC++ 2010 and above, which have added new values in the range 100-140. Some versions of gcc-4.8.0 and above are now catching up and provide some of these new values too (e.g. binaries from http://mingw-w64.sourceforge.net/ but not currently those from http://www.mingw.org/), but they don't provide all of them. EADDRINUSE is provided, so convert_errno_to_wsa_error() gets included, but the compilation fails because the following #defines which VC++ 2010 and above provide are missing: EBADMSG EIDRM ENODATA ENOLINK ENOMSG ENOSR ENOSTR ENOTRECOVERABLE EOTHER ETIME ETXTBSY Simply ignore (#ifdef away) these constants for those compilers that don't provide them. --- win32/include/sys/errno2.h | 10 +++++----- win32/win32.c | 12 ++++++------ win32/win32sck.c | 48 +++++++++++++++++++++++++++++++++++----------- 3 files changed, 48 insertions(+), 22 deletions(-) diff --git a/win32/include/sys/errno2.h b/win32/include/sys/errno2.h index a06fb4a..3ca85e3 100644 --- a/win32/include/sys/errno2.h +++ b/win32/include/sys/errno2.h @@ -13,10 +13,10 @@ /* Ensure all the Exxx constants required by convert_wsa_error_to_errno() in * win32/win32sck.c are defined. Many are defined in already (more so - * in VC++ 2010 and above, which have an extra "POSIX supplement") so, for the - * sake of compatibility with third-party code linked into XS modules, we must - * be careful not to redefine them; for the remainder we define our own values, - * namely the corresponding WSAExxx values. + * in VC++ 2010 and above and some MinGW/gcc-4.8 and above, which have an extra + * "POSIX supplement") so, for the sake of compatibility with third-party code + * linked into XS modules, we must be careful not to redefine them; for the + * remainder we define our own values, namely the corresponding WSAExxx values. * * These definitions are also used as a supplement to the use of in * the Errno and POSIX modules, both of which may be used to test the value of @@ -24,7 +24,7 @@ * and the $! case in Perl_magic_set()). It also provides numerous otherwise * missing values in the (hard-coded) list of Exxx constants exported by POSIX. * Finally, three of the non-standard errno.h values (actually all now in the - * POSIX supplement in VC10+) are used in the perl core. + * POSIX supplement in VC10+ and some MinGW/gcc-4.8+) are used in the perl core. * * This list is in the same order as that in convert_wsa_error_to_errno(). A * handful of WSAExxx constants used by that function have no corresponding Exxx diff --git a/win32/win32.c b/win32/win32.c index 5322881..53962b2 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -2610,12 +2610,12 @@ win32_strerror(int e) if (e < 0) e = GetLastError(); #ifdef ERRNO_HAS_POSIX_SUPPLEMENT - /* VC10+ define a "POSIX supplement" of errno values ranging from - * EADDRINUSE (100) to EWOULDBLOCK (140), but sys_nerr is still 43 and - * strerror() returns "Unknown error" for them. We must therefore still - * roll our own messages for these codes, and additionally map them to - * corresponding Windows (sockets) error codes first to avoid getting - * the wrong system message. + /* VC10+ and some MinGW/gcc-4.8+ define a "POSIX supplement" of errno + * values ranging from EADDRINUSE (100) to EWOULDBLOCK (140), but + * sys_nerr is still 43 and strerror() returns "Unknown error" for them. + * We must therefore still roll our own messages for these codes, and + * additionally map them to corresponding Windows (sockets) error codes + * first to avoid getting the wrong system message. */ else if (e >= EADDRINUSE && e <= EWOULDBLOCK) { e = convert_errno_to_wsa_error(e); diff --git a/win32/win32sck.c b/win32/win32sck.c index 5032cf0..5f98910 100644 --- a/win32/win32sck.c +++ b/win32/win32sck.c @@ -194,6 +194,10 @@ convert_wsa_error_to_errno(int wsaerr) * we just use ERROR_INVALID_FUNCTION for those that are missing but do not * really expect to encounter them anyway in the context in which this function * is called. + * Some versions of MinGW/gcc-4.8 and above also define most, but not all, of + * these extra Exxx values. The missing ones are all cases for which there is no + * corresponding WSAExxx constant anyway, so we simply omit the cases for them + * here. * Other Exxx values (err < sys_nerr) are returned unchanged. */ int @@ -208,8 +212,10 @@ convert_errno_to_wsa_error(int err) return WSAEAFNOSUPPORT; case EALREADY: return WSAEALREADY; - case EBADMSG: +#ifdef EBADMSG + case EBADMSG: /* Not defined in gcc-4.8.0 */ return ERROR_INVALID_FUNCTION; +#endif case ECANCELED: #ifdef WSAECANCELLED return WSAECANCELLED; /* New in WinSock2 */ @@ -226,8 +232,10 @@ convert_errno_to_wsa_error(int err) return WSAEDESTADDRREQ; case EHOSTUNREACH: return WSAEHOSTUNREACH; - case EIDRM: +#ifdef EIDRM + case EIDRM: /* Not defined in gcc-4.8.0 */ return ERROR_INVALID_FUNCTION; +#endif case EINPROGRESS: return WSAEINPROGRESS; case EISCONN: @@ -244,30 +252,44 @@ convert_errno_to_wsa_error(int err) return WSAENETUNREACH; case ENOBUFS: return WSAENOBUFS; - case ENODATA: +#ifdef ENODATA + case ENODATA: /* Not defined in gcc-4.8.0 */ return ERROR_INVALID_FUNCTION; - case ENOLINK: +#endif +#ifdef ENOLINK + case ENOLINK: /* Not defined in gcc-4.8.0 */ return ERROR_INVALID_FUNCTION; - case ENOMSG: +#endif +#ifdef ENOMSG + case ENOMSG: /* Not defined in gcc-4.8.0 */ return ERROR_INVALID_FUNCTION; +#endif case ENOPROTOOPT: return WSAENOPROTOOPT; - case ENOSR: +#ifdef ENOSR + case ENOSR: /* Not defined in gcc-4.8.0 */ return ERROR_INVALID_FUNCTION; - case ENOSTR: +#endif +#ifdef ENOSTR + case ENOSTR: /* Not defined in gcc-4.8.0 */ return ERROR_INVALID_FUNCTION; +#endif case ENOTCONN: return WSAENOTCONN; - case ENOTRECOVERABLE: +#ifdef ENOTRECOVERABLE + case ENOTRECOVERABLE: /* Not defined in gcc-4.8.0 */ return ERROR_INVALID_FUNCTION; +#endif case ENOTSOCK: return WSAENOTSOCK; case ENOTSUP: return ERROR_INVALID_FUNCTION; case EOPNOTSUPP: return WSAEOPNOTSUPP; - case EOTHER: +#ifdef EOTHER + case EOTHER: /* Not defined in gcc-4.8.0 */ return ERROR_INVALID_FUNCTION; +#endif case EOVERFLOW: return ERROR_INVALID_FUNCTION; case EOWNERDEAD: @@ -278,12 +300,16 @@ convert_errno_to_wsa_error(int err) return WSAEPROTONOSUPPORT; case EPROTOTYPE: return WSAEPROTOTYPE; - case ETIME: +#ifdef ETIME + case ETIME: /* Not defined in gcc-4.8.0 */ return ERROR_INVALID_FUNCTION; +#endif case ETIMEDOUT: return WSAETIMEDOUT; - case ETXTBSY: +#ifdef ETXTBSY + case ETXTBSY: /* Not defined in gcc-4.8.0 */ return ERROR_INVALID_FUNCTION; +#endif case EWOULDBLOCK: return WSAEWOULDBLOCK; } -- 2.7.4