From 765a40603897ad60a0ca2bdb5c93f43b55261470 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sat, 29 Apr 2017 13:23:28 +0200 Subject: [PATCH] strerror_r-posix: Fixes for MSVC 14. * lib/strerror_r.c: Include . (strerror_r): Provide error messages for errno values 100...140. * doc/posix-functions/strerror_r.texi: Mention the MSVC 14 problem. --- ChangeLog | 7 ++ doc/posix-functions/strerror_r.texi | 4 + lib/strerror_r.c | 112 ++++++++++++++++++++++++++++ 3 files changed, 123 insertions(+) diff --git a/ChangeLog b/ChangeLog index 00d9277aaa..d641fb7841 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2017-04-29 Bruno Haible + + strerror_r-posix: Fixes for MSVC 14. + * lib/strerror_r.c: Include . + (strerror_r): Provide error messages for errno values 100...140. + * doc/posix-functions/strerror_r.texi: Mention the MSVC 14 problem. + 2017-04-28 Bruno Haible noreturn: New module. diff --git a/doc/posix-functions/strerror_r.texi b/doc/posix-functions/strerror_r.texi index 06fdfd224d..8554a29ae7 100644 --- a/doc/posix-functions/strerror_r.texi +++ b/doc/posix-functions/strerror_r.texi @@ -39,6 +39,10 @@ glibc 2.12 with @code{-D_POSIX_C_SOURCE=200112L}, AIX 6.1, OSF/1 5.1. When this function fails, it corrupts @code{errno}, on some platforms: Solaris 10. @item +This function does not support many error values defined in @code{} on +some platforms: +MSVC 14. +@item This function does not support the error values that are specified by POSIX but not defined by the system, on some platforms: OpenBSD 4.0, OSF/1 5.1, NonStop Kernel, Cygwin 1.5.x. diff --git a/lib/strerror_r.c b/lib/strerror_r.c index d7b0f778f0..650751fc8d 100644 --- a/lib/strerror_r.c +++ b/lib/strerror_r.c @@ -28,6 +28,9 @@ #include #include #include +#if !HAVE_SNPRINTF +# include +#endif #include "strerror-override.h" @@ -327,6 +330,115 @@ strerror_r (int errnum, char *buf, size_t buflen) # endif +#endif + +#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__ + /* MSVC 14 defines names for many error codes in the range 100..140, + but _sys_errlist contains strings only for the error codes + < _sys_nerr = 43. */ + if (ret == EINVAL) + { + const char *errmsg; + + switch (errnum) + { + case 100 /* EADDRINUSE */: + errmsg = "Address already in use"; + break; + case 101 /* EADDRNOTAVAIL */: + errmsg = "Cannot assign requested address"; + break; + case 102 /* EAFNOSUPPORT */: + errmsg = "Address family not supported by protocol"; + break; + case 103 /* EALREADY */: + errmsg = "Operation already in progress"; + break; + case 105 /* ECANCELED */: + errmsg = "Operation canceled"; + break; + case 106 /* ECONNABORTED */: + errmsg = "Software caused connection abort"; + break; + case 107 /* ECONNREFUSED */: + errmsg = "Connection refused"; + break; + case 108 /* ECONNRESET */: + errmsg = "Connection reset by peer"; + break; + case 109 /* EDESTADDRREQ */: + errmsg = "Destination address required"; + break; + case 110 /* EHOSTUNREACH */: + errmsg = "No route to host"; + break; + case 112 /* EINPROGRESS */: + errmsg = "Operation now in progress"; + break; + case 113 /* EISCONN */: + errmsg = "Transport endpoint is already connected"; + break; + case 114 /* ELOOP */: + errmsg = "Too many levels of symbolic links"; + break; + case 115 /* EMSGSIZE */: + errmsg = "Message too long"; + break; + case 116 /* ENETDOWN */: + errmsg = "Network is down"; + break; + case 117 /* ENETRESET */: + errmsg = "Network dropped connection on reset"; + break; + case 118 /* ENETUNREACH */: + errmsg = "Network is unreachable"; + break; + case 119 /* ENOBUFS */: + errmsg = "No buffer space available"; + break; + case 123 /* ENOPROTOOPT */: + errmsg = "Protocol not available"; + break; + case 126 /* ENOTCONN */: + errmsg = "Transport endpoint is not connected"; + break; + case 128 /* ENOTSOCK */: + errmsg = "Socket operation on non-socket"; + break; + case 129 /* ENOTSUP */: + errmsg = "Not supported"; + break; + case 130 /* EOPNOTSUPP */: + errmsg = "Operation not supported"; + break; + case 132 /* EOVERFLOW */: + errmsg = "Value too large for defined data type"; + break; + case 133 /* EOWNERDEAD */: + errmsg = "Owner died"; + break; + case 134 /* EPROTO */: + errmsg = "Protocol error"; + break; + case 135 /* EPROTONOSUPPORT */: + errmsg = "Protocol not supported"; + break; + case 136 /* EPROTOTYPE */: + errmsg = "Protocol wrong type for socket"; + break; + case 138 /* ETIMEDOUT */: + errmsg = "Connection timed out"; + break; + case 140 /* EWOULDBLOCK */: + errmsg = "Operation would block"; + break; + default: + errmsg = NULL; + break; + } + if (errmsg != NULL) + ret = safe_copy (buf, buflen, errmsg); + } #endif if (ret == EINVAL && !*buf) -- 2.39.5