* modules/strerror-override: New module. * lib/strerror_r.c (strerror_r): Move gnulib replacement strings... * lib/strerror-override.c (strerror_override): ...to new file. * lib/strerror-override.h: Add prototype. * lib/strerror-impl.h: Delete. * lib/strerror.c (strerror): New implementation. * modules/strerror_r-posix (Files): Add new files. * modules/strerror (Files): Likewise. (Depends-on): Drop strerror_r-posix. * MODULES.html.sh: Document new module and strerror_r-posix. Requested by Sam Steingold.
Signed-off-by: Eric Blake <ebl...@redhat.com> --- A new module is required because both strerror and strerror_r might need strerror-override.o, but they might be in different directories (one in lib and one in tests), and we can only AC_LIBOBJ it once. Now, just the strerror module in isolation does not drag in strerror_r. Tested on glibc with: gl_cv_header_errno_h_complete=no gl_cv_func_working_strerror=no \ gl_cv_func_strerror_r_works=no ./gnulib-tool --with-tests \ --test strerror strerror_r-posix Hmm, perhaps I should move strerror-override.c to be part of the errno module, rather than making it a separate module. That is, the only time the strerror_override() function should be compiled is if our replacement errno.h added new values. ChangeLog | 13 ++ MODULES.html.sh | 2 + lib/strerror-impl.h | 42 ------ lib/strerror-override.c | 347 +++++++++++++++++++++++++++++++++++++++++++++ lib/strerror-override.h | 48 ++++++ lib/strerror.c | 36 +++++- lib/strerror_r.c | 318 +---------------------------------------- modules/strerror | 9 +- modules/strerror-override | 26 ++++ modules/strerror_r-posix | 1 + 10 files changed, 479 insertions(+), 363 deletions(-) delete mode 100644 lib/strerror-impl.h create mode 100644 lib/strerror-override.c create mode 100644 lib/strerror-override.h create mode 100644 modules/strerror-override diff --git a/ChangeLog b/ChangeLog index a66e44d..1aeaa33 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,18 @@ 2011-05-24 Eric Blake <ebl...@redhat.com> + strerror: drop strerror_r dependency + * modules/strerror-override: New module. + * lib/strerror_r.c (strerror_r): Move gnulib replacement strings... + * lib/strerror-override.c (strerror_override): ...to new file. + * lib/strerror-override.h: Add prototype. + * lib/strerror-impl.h: Delete. + * lib/strerror.c (strerror): New implementation. + * modules/strerror_r-posix (Files): Add new files. + * modules/strerror (Files): Likewise. + (Depends-on): Drop strerror_r-posix. + * MODULES.html.sh: Document new module and strerror_r-posix. + Requested by Sam Steingold. + perror: call strerror_r directly * modules/perror (Files): Drop strerror-impl.h. * lib/perror.c (perror): Use our own stack buffer, rather than diff --git a/MODULES.html.sh b/MODULES.html.sh index 18a7472..26c3fa9 100755 --- a/MODULES.html.sh +++ b/MODULES.html.sh @@ -1626,6 +1626,7 @@ func_all_modules () func_module atexit func_module strtod func_module strerror + func_module strerror-override func_module mktime func_end_table @@ -1789,6 +1790,7 @@ func_all_modules () func_module strcasestr-simple func_module strchrnul func_module streq + func_module strerror_r-posix func_module strnlen func_module strnlen1 func_module strndup diff --git a/lib/strerror-impl.h b/lib/strerror-impl.h deleted file mode 100644 index a204243..0000000 --- a/lib/strerror-impl.h +++ /dev/null @@ -1,42 +0,0 @@ -/* strerror-impl.h --- Implementation of POSIX compatible strerror() function. - - Copyright (C) 2007-2011 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -#ifdef STATIC -STATIC -#endif -char * -strerror (int n) -{ - static char buf[256]; - - int ret = strerror_r (n, buf, sizeof (buf)); - - if (ret == 0) - return buf; - - if (ret == ERANGE) - /* If this happens, increase the size of buf. */ - abort (); - - { - static char const fmt[] = "Unknown error (%d)"; - verify (sizeof (buf) >= sizeof (fmt) + INT_STRLEN_BOUND (n)); - sprintf (buf, fmt, n); - errno = ret; - return buf; - } -} diff --git a/lib/strerror-override.c b/lib/strerror-override.c new file mode 100644 index 0000000..5fcbe1f --- /dev/null +++ b/lib/strerror-override.c @@ -0,0 +1,347 @@ +/* strerror-override.c --- POSIX compatible system error routine + + Copyright (C) 2010-2011 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +/* Written by Bruno Haible <br...@clisp.org>, 2010. */ + +#include "strerror-override.h" + +#include <errno.h> + +#if GNULIB_defined_ESOCK /* native Windows platforms */ +# if HAVE_WINSOCK2_H +# include <winsock2.h> +# endif +#endif + +/* This undefine allows testing with gl_cv_header_errno_h_complete=no on + a system that otherwise has a complete errno.h. */ +#undef strerror_override + +/* If ERRNUM maps to an errno value defined by gnulib, return a string + describing the error. Otherwise return NULL. */ +const char * +strerror_override (int errnum) +{ + const char *msg = NULL; + +#if GNULIB_defined_ETXTBSY \ + || GNULIB_defined_ESOCK \ + || GNULIB_defined_ENOMSG \ + || GNULIB_defined_EIDRM \ + || GNULIB_defined_ENOLINK \ + || GNULIB_defined_EPROTO \ + || GNULIB_defined_EMULTIHOP \ + || GNULIB_defined_EBADMSG \ + || GNULIB_defined_EOVERFLOW \ + || GNULIB_defined_ENOTSUP \ + || GNULIB_defined_ESTALE \ + || GNULIB_defined_EDQUOT \ + || GNULIB_defined_ECANCELED + /* These error messages are taken from glibc/sysdeps/gnu/errlist.c. */ + switch (errnum) + { +# if GNULIB_defined_ETXTBSY + case ETXTBSY: + msg = "Text file busy"; + break; +# endif + +# if GNULIB_defined_ESOCK /* native Windows platforms */ + /* EWOULDBLOCK is the same as EAGAIN. */ + case EINPROGRESS: + msg = "Operation now in progress"; + break; + case EALREADY: + msg = "Operation already in progress"; + break; + case ENOTSOCK: + msg = "Socket operation on non-socket"; + break; + case EDESTADDRREQ: + msg = "Destination address required"; + break; + case EMSGSIZE: + msg = "Message too long"; + break; + case EPROTOTYPE: + msg = "Protocol wrong type for socket"; + break; + case ENOPROTOOPT: + msg = "Protocol not available"; + break; + case EPROTONOSUPPORT: + msg = "Protocol not supported"; + break; + case ESOCKTNOSUPPORT: + msg = "Socket type not supported"; + break; + case EOPNOTSUPP: + msg = "Operation not supported"; + break; + case EPFNOSUPPORT: + msg = "Protocol family not supported"; + break; + case EAFNOSUPPORT: + msg = "Address family not supported by protocol"; + break; + case EADDRINUSE: + msg = "Address already in use"; + break; + case EADDRNOTAVAIL: + msg = "Cannot assign requested address"; + break; + case ENETDOWN: + msg = "Network is down"; + break; + case ENETUNREACH: + msg = "Network is unreachable"; + break; + case ENETRESET: + msg = "Network dropped connection on reset"; + break; + case ECONNABORTED: + msg = "Software caused connection abort"; + break; + case ECONNRESET: + msg = "Connection reset by peer"; + break; + case ENOBUFS: + msg = "No buffer space available"; + break; + case EISCONN: + msg = "Transport endpoint is already connected"; + break; + case ENOTCONN: + msg = "Transport endpoint is not connected"; + break; + case ESHUTDOWN: + msg = "Cannot send after transport endpoint shutdown"; + break; + case ETOOMANYREFS: + msg = "Too many references: cannot splice"; + break; + case ETIMEDOUT: + msg = "Connection timed out"; + break; + case ECONNREFUSED: + msg = "Connection refused"; + break; + case ELOOP: + msg = "Too many levels of symbolic links"; + break; + case EHOSTDOWN: + msg = "Host is down"; + break; + case EHOSTUNREACH: + msg = "No route to host"; + break; + case EPROCLIM: + msg = "Too many processes"; + break; + case EUSERS: + msg = "Too many users"; + break; + case EDQUOT: + msg = "Disk quota exceeded"; + break; + case ESTALE: + msg = "Stale NFS file handle"; + break; + case EREMOTE: + msg = "Object is remote"; + break; +# if HAVE_WINSOCK2_H + /* WSA_INVALID_HANDLE maps to EBADF */ + /* WSA_NOT_ENOUGH_MEMORY maps to ENOMEM */ + /* WSA_INVALID_PARAMETER maps to EINVAL */ + case WSA_OPERATION_ABORTED: + msg = "Overlapped operation aborted"; + break; + case WSA_IO_INCOMPLETE: + msg = "Overlapped I/O event object not in signaled state"; + break; + case WSA_IO_PENDING: + msg = "Overlapped operations will complete later"; + break; + /* WSAEINTR maps to EINTR */ + /* WSAEBADF maps to EBADF */ + /* WSAEACCES maps to EACCES */ + /* WSAEFAULT maps to EFAULT */ + /* WSAEINVAL maps to EINVAL */ + /* WSAEMFILE maps to EMFILE */ + /* WSAEWOULDBLOCK maps to EWOULDBLOCK */ + /* WSAEINPROGRESS is EINPROGRESS */ + /* WSAEALREADY is EALREADY */ + /* WSAENOTSOCK is ENOTSOCK */ + /* WSAEDESTADDRREQ is EDESTADDRREQ */ + /* WSAEMSGSIZE is EMSGSIZE */ + /* WSAEPROTOTYPE is EPROTOTYPE */ + /* WSAENOPROTOOPT is ENOPROTOOPT */ + /* WSAEPROTONOSUPPORT is EPROTONOSUPPORT */ + /* WSAESOCKTNOSUPPORT is ESOCKTNOSUPPORT */ + /* WSAEOPNOTSUPP is EOPNOTSUPP */ + /* WSAEPFNOSUPPORT is EPFNOSUPPORT */ + /* WSAEAFNOSUPPORT is EAFNOSUPPORT */ + /* WSAEADDRINUSE is EADDRINUSE */ + /* WSAEADDRNOTAVAIL is EADDRNOTAVAIL */ + /* WSAENETDOWN is ENETDOWN */ + /* WSAENETUNREACH is ENETUNREACH */ + /* WSAENETRESET is ENETRESET */ + /* WSAECONNABORTED is ECONNABORTED */ + /* WSAECONNRESET is ECONNRESET */ + /* WSAENOBUFS is ENOBUFS */ + /* WSAEISCONN is EISCONN */ + /* WSAENOTCONN is ENOTCONN */ + /* WSAESHUTDOWN is ESHUTDOWN */ + /* WSAETOOMANYREFS is ETOOMANYREFS */ + /* WSAETIMEDOUT is ETIMEDOUT */ + /* WSAECONNREFUSED is ECONNREFUSED */ + /* WSAELOOP is ELOOP */ + /* WSAENAMETOOLONG maps to ENAMETOOLONG */ + /* WSAEHOSTDOWN is EHOSTDOWN */ + /* WSAEHOSTUNREACH is EHOSTUNREACH */ + /* WSAENOTEMPTY maps to ENOTEMPTY */ + /* WSAEPROCLIM is EPROCLIM */ + /* WSAEUSERS is EUSERS */ + /* WSAEDQUOT is EDQUOT */ + /* WSAESTALE is ESTALE */ + /* WSAEREMOTE is EREMOTE */ + case WSASYSNOTREADY: + msg = "Network subsystem is unavailable"; + break; + case WSAVERNOTSUPPORTED: + msg = "Winsock.dll version out of range"; + break; + case WSANOTINITIALISED: + msg = "Successful WSAStartup not yet performed"; + break; + case WSAEDISCON: + msg = "Graceful shutdown in progress"; + break; + case WSAENOMORE: case WSA_E_NO_MORE: + msg = "No more results"; + break; + case WSAECANCELLED: case WSA_E_CANCELLED: + msg = "Call was canceled"; + break; + case WSAEINVALIDPROCTABLE: + msg = "Procedure call table is invalid"; + break; + case WSAEINVALIDPROVIDER: + msg = "Service provider is invalid"; + break; + case WSAEPROVIDERFAILEDINIT: + msg = "Service provider failed to initialize"; + break; + case WSASYSCALLFAILURE: + msg = "System call failure"; + break; + case WSASERVICE_NOT_FOUND: + msg = "Service not found"; + break; + case WSATYPE_NOT_FOUND: + msg = "Class type not found"; + break; + case WSAEREFUSED: + msg = "Database query was refused"; + break; + case WSAHOST_NOT_FOUND: + msg = "Host not found"; + break; + case WSATRY_AGAIN: + msg = "Nonauthoritative host not found"; + break; + case WSANO_RECOVERY: + msg = "Nonrecoverable error"; + break; + case WSANO_DATA: + msg = "Valid name, no data record of requested type"; + break; + /* WSA_QOS_* omitted */ +# endif +# endif + +# if GNULIB_defined_ENOMSG + case ENOMSG: + msg = "No message of desired type"; + break; +# endif + +# if GNULIB_defined_EIDRM + case EIDRM: + msg = "Identifier removed"; + break; +# endif + +# if GNULIB_defined_ENOLINK + case ENOLINK: + msg = "Link has been severed"; + break; +# endif + +# if GNULIB_defined_EPROTO + case EPROTO: + msg = "Protocol error"; + break; +# endif + +# if GNULIB_defined_EMULTIHOP + case EMULTIHOP: + msg = "Multihop attempted"; + break; +# endif + +# if GNULIB_defined_EBADMSG + case EBADMSG: + msg = "Bad message"; + break; +# endif + +# if GNULIB_defined_EOVERFLOW + case EOVERFLOW: + msg = "Value too large for defined data type"; + break; +# endif + +# if GNULIB_defined_ENOTSUP + case ENOTSUP: + msg = "Not supported"; + break; +# endif + +# if GNULIB_defined_ESTALE + case ESTALE: + msg = "Stale NFS file handle"; + break; +# endif + +# if GNULIB_defined_EDQUOT + case EDQUOT: + msg = "Disk quota exceeded"; + break; +# endif + +# if GNULIB_defined_ECANCELED + case ECANCELED: + msg = "Operation canceled"; + break; +# endif + } +#endif + + return msg; +} diff --git a/lib/strerror-override.h b/lib/strerror-override.h new file mode 100644 index 0000000..0718b53 --- /dev/null +++ b/lib/strerror-override.h @@ -0,0 +1,48 @@ +/* strerror-override.h --- POSIX compatible system error routine + + Copyright (C) 2010-2011 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. */ + +#ifndef _GL_STRERROR_OVERRIDE_H +# define _GL_STRERROR_OVERRIDE_H + +# include <string.h> + +/* Reasonable buffer size that should never trigger ERANGE; if this + proves too small, we intentionally abort(), to remind us to fix + this value. */ +# define STACKBUF_LEN 256 + +/* If ERRNUM maps to an errno value defined by gnulib, return a string + describing the error. Otherwise return NULL. */ +# if GNULIB_defined_ETXTBSY \ + || GNULIB_defined_ESOCK \ + || GNULIB_defined_ENOMSG \ + || GNULIB_defined_EIDRM \ + || GNULIB_defined_ENOLINK \ + || GNULIB_defined_EPROTO \ + || GNULIB_defined_EMULTIHOP \ + || GNULIB_defined_EBADMSG \ + || GNULIB_defined_EOVERFLOW \ + || GNULIB_defined_ENOTSUP \ + || GNULIB_defined_ESTALE \ + || GNULIB_defined_EDQUOT \ + || GNULIB_defined_ECANCELED +extern const char *strerror_override (int errnum); +# else +# define strerror_override(ignored) NULL +# endif + +#endif /* _GL_STRERROR_OVERRIDE_H */ diff --git a/lib/strerror.c b/lib/strerror.c index 9d1f165..8c41179 100644 --- a/lib/strerror.c +++ b/lib/strerror.c @@ -23,11 +23,45 @@ #include <errno.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> #include "intprops.h" +#include "strerror-override.h" #include "verify.h" /* Use the system functions, not the gnulib overrides in this file. */ #undef sprintf -#include "strerror-impl.h" +char * +strerror (int n) +#undef strerror +{ + static char buf[STACKBUF_LEN]; + size_t len; + + /* Cast away const, due to the historical signature of strerror; + callers should not be modifying the string. */ + const char *msg = strerror_override (n); + if (msg) + return (char *) msg; + + /* Our strerror_r implementation might use the system's strerror + buffer, so all other clients of strerror have to see the error + copied into a buffer that we manage. */ + msg = strerror (n); + if (!msg || !*msg) + { + static char const fmt[] = "Unknown error %d"; + verify (sizeof buf >= sizeof (fmt) + INT_STRLEN_BOUND (n)); + sprintf (buf, fmt, n); + errno = EINVAL; + return buf; + } + + /* Fix STACKBUF_LEN if this ever aborts. */ + len = strlen (msg); + if (sizeof buf <= len) + abort (); + + return memcpy (buf, msg, len + 1); +} diff --git a/lib/strerror_r.c b/lib/strerror_r.c index 494b1f0..462455d 100644 --- a/lib/strerror_r.c +++ b/lib/strerror_r.c @@ -28,16 +28,7 @@ #include <errno.h> #include <stdio.h> -#if GNULIB_defined_ESOCK /* native Windows platforms */ -# if HAVE_WINSOCK2_H -# include <winsock2.h> -# endif -#endif - -/* Reasonable buffer size that should never trigger ERANGE; if this - proves too small, we intentionally abort(), to remind us to fix - this value as well as strerror-impl.h. */ -#define STACKBUF_LEN 256 +#include "strerror-override.h" #if (__GLIBC__ >= 2 || defined __UCLIBC__ || defined __CYGWIN__) && HAVE___XPG_STRERROR_R /* glibc >= 2.3.4, cygwin >= 1.7.9 */ @@ -136,316 +127,13 @@ strerror_r (int errnum, char *buf, size_t buflen) } *buf = '\0'; -#if GNULIB_defined_ETXTBSY \ - || GNULIB_defined_ESOCK \ - || GNULIB_defined_ENOMSG \ - || GNULIB_defined_EIDRM \ - || GNULIB_defined_ENOLINK \ - || GNULIB_defined_EPROTO \ - || GNULIB_defined_EMULTIHOP \ - || GNULIB_defined_EBADMSG \ - || GNULIB_defined_EOVERFLOW \ - || GNULIB_defined_ENOTSUP \ - || GNULIB_defined_ESTALE \ - || GNULIB_defined_EDQUOT \ - || GNULIB_defined_ECANCELED + /* Check for gnulib overrides. */ { - char const *msg = NULL; - /* These error messages are taken from glibc/sysdeps/gnu/errlist.c. */ - switch (errnum) - { -# if GNULIB_defined_ETXTBSY - case ETXTBSY: - msg = "Text file busy"; - break; -# endif - -# if GNULIB_defined_ESOCK /* native Windows platforms */ - /* EWOULDBLOCK is the same as EAGAIN. */ - case EINPROGRESS: - msg = "Operation now in progress"; - break; - case EALREADY: - msg = "Operation already in progress"; - break; - case ENOTSOCK: - msg = "Socket operation on non-socket"; - break; - case EDESTADDRREQ: - msg = "Destination address required"; - break; - case EMSGSIZE: - msg = "Message too long"; - break; - case EPROTOTYPE: - msg = "Protocol wrong type for socket"; - break; - case ENOPROTOOPT: - msg = "Protocol not available"; - break; - case EPROTONOSUPPORT: - msg = "Protocol not supported"; - break; - case ESOCKTNOSUPPORT: - msg = "Socket type not supported"; - break; - case EOPNOTSUPP: - msg = "Operation not supported"; - break; - case EPFNOSUPPORT: - msg = "Protocol family not supported"; - break; - case EAFNOSUPPORT: - msg = "Address family not supported by protocol"; - break; - case EADDRINUSE: - msg = "Address already in use"; - break; - case EADDRNOTAVAIL: - msg = "Cannot assign requested address"; - break; - case ENETDOWN: - msg = "Network is down"; - break; - case ENETUNREACH: - msg = "Network is unreachable"; - break; - case ENETRESET: - msg = "Network dropped connection on reset"; - break; - case ECONNABORTED: - msg = "Software caused connection abort"; - break; - case ECONNRESET: - msg = "Connection reset by peer"; - break; - case ENOBUFS: - msg = "No buffer space available"; - break; - case EISCONN: - msg = "Transport endpoint is already connected"; - break; - case ENOTCONN: - msg = "Transport endpoint is not connected"; - break; - case ESHUTDOWN: - msg = "Cannot send after transport endpoint shutdown"; - break; - case ETOOMANYREFS: - msg = "Too many references: cannot splice"; - break; - case ETIMEDOUT: - msg = "Connection timed out"; - break; - case ECONNREFUSED: - msg = "Connection refused"; - break; - case ELOOP: - msg = "Too many levels of symbolic links"; - break; - case EHOSTDOWN: - msg = "Host is down"; - break; - case EHOSTUNREACH: - msg = "No route to host"; - break; - case EPROCLIM: - msg = "Too many processes"; - break; - case EUSERS: - msg = "Too many users"; - break; - case EDQUOT: - msg = "Disk quota exceeded"; - break; - case ESTALE: - msg = "Stale NFS file handle"; - break; - case EREMOTE: - msg = "Object is remote"; - break; -# if HAVE_WINSOCK2_H - /* WSA_INVALID_HANDLE maps to EBADF */ - /* WSA_NOT_ENOUGH_MEMORY maps to ENOMEM */ - /* WSA_INVALID_PARAMETER maps to EINVAL */ - case WSA_OPERATION_ABORTED: - msg = "Overlapped operation aborted"; - break; - case WSA_IO_INCOMPLETE: - msg = "Overlapped I/O event object not in signaled state"; - break; - case WSA_IO_PENDING: - msg = "Overlapped operations will complete later"; - break; - /* WSAEINTR maps to EINTR */ - /* WSAEBADF maps to EBADF */ - /* WSAEACCES maps to EACCES */ - /* WSAEFAULT maps to EFAULT */ - /* WSAEINVAL maps to EINVAL */ - /* WSAEMFILE maps to EMFILE */ - /* WSAEWOULDBLOCK maps to EWOULDBLOCK */ - /* WSAEINPROGRESS is EINPROGRESS */ - /* WSAEALREADY is EALREADY */ - /* WSAENOTSOCK is ENOTSOCK */ - /* WSAEDESTADDRREQ is EDESTADDRREQ */ - /* WSAEMSGSIZE is EMSGSIZE */ - /* WSAEPROTOTYPE is EPROTOTYPE */ - /* WSAENOPROTOOPT is ENOPROTOOPT */ - /* WSAEPROTONOSUPPORT is EPROTONOSUPPORT */ - /* WSAESOCKTNOSUPPORT is ESOCKTNOSUPPORT */ - /* WSAEOPNOTSUPP is EOPNOTSUPP */ - /* WSAEPFNOSUPPORT is EPFNOSUPPORT */ - /* WSAEAFNOSUPPORT is EAFNOSUPPORT */ - /* WSAEADDRINUSE is EADDRINUSE */ - /* WSAEADDRNOTAVAIL is EADDRNOTAVAIL */ - /* WSAENETDOWN is ENETDOWN */ - /* WSAENETUNREACH is ENETUNREACH */ - /* WSAENETRESET is ENETRESET */ - /* WSAECONNABORTED is ECONNABORTED */ - /* WSAECONNRESET is ECONNRESET */ - /* WSAENOBUFS is ENOBUFS */ - /* WSAEISCONN is EISCONN */ - /* WSAENOTCONN is ENOTCONN */ - /* WSAESHUTDOWN is ESHUTDOWN */ - /* WSAETOOMANYREFS is ETOOMANYREFS */ - /* WSAETIMEDOUT is ETIMEDOUT */ - /* WSAECONNREFUSED is ECONNREFUSED */ - /* WSAELOOP is ELOOP */ - /* WSAENAMETOOLONG maps to ENAMETOOLONG */ - /* WSAEHOSTDOWN is EHOSTDOWN */ - /* WSAEHOSTUNREACH is EHOSTUNREACH */ - /* WSAENOTEMPTY maps to ENOTEMPTY */ - /* WSAEPROCLIM is EPROCLIM */ - /* WSAEUSERS is EUSERS */ - /* WSAEDQUOT is EDQUOT */ - /* WSAESTALE is ESTALE */ - /* WSAEREMOTE is EREMOTE */ - case WSASYSNOTREADY: - msg = "Network subsystem is unavailable"; - break; - case WSAVERNOTSUPPORTED: - msg = "Winsock.dll version out of range"; - break; - case WSANOTINITIALISED: - msg = "Successful WSAStartup not yet performed"; - break; - case WSAEDISCON: - msg = "Graceful shutdown in progress"; - break; - case WSAENOMORE: case WSA_E_NO_MORE: - msg = "No more results"; - break; - case WSAECANCELLED: case WSA_E_CANCELLED: - msg = "Call was canceled"; - break; - case WSAEINVALIDPROCTABLE: - msg = "Procedure call table is invalid"; - break; - case WSAEINVALIDPROVIDER: - msg = "Service provider is invalid"; - break; - case WSAEPROVIDERFAILEDINIT: - msg = "Service provider failed to initialize"; - break; - case WSASYSCALLFAILURE: - msg = "System call failure"; - break; - case WSASERVICE_NOT_FOUND: - msg = "Service not found"; - break; - case WSATYPE_NOT_FOUND: - msg = "Class type not found"; - break; - case WSAEREFUSED: - msg = "Database query was refused"; - break; - case WSAHOST_NOT_FOUND: - msg = "Host not found"; - break; - case WSATRY_AGAIN: - msg = "Nonauthoritative host not found"; - break; - case WSANO_RECOVERY: - msg = "Nonrecoverable error"; - break; - case WSANO_DATA: - msg = "Valid name, no data record of requested type"; - break; - /* WSA_QOS_* omitted */ -# endif -# endif - -# if GNULIB_defined_ENOMSG - case ENOMSG: - msg = "No message of desired type"; - break; -# endif - -# if GNULIB_defined_EIDRM - case EIDRM: - msg = "Identifier removed"; - break; -# endif - -# if GNULIB_defined_ENOLINK - case ENOLINK: - msg = "Link has been severed"; - break; -# endif - -# if GNULIB_defined_EPROTO - case EPROTO: - msg = "Protocol error"; - break; -# endif - -# if GNULIB_defined_EMULTIHOP - case EMULTIHOP: - msg = "Multihop attempted"; - break; -# endif - -# if GNULIB_defined_EBADMSG - case EBADMSG: - msg = "Bad message"; - break; -# endif - -# if GNULIB_defined_EOVERFLOW - case EOVERFLOW: - msg = "Value too large for defined data type"; - break; -# endif - -# if GNULIB_defined_ENOTSUP - case ENOTSUP: - msg = "Not supported"; - break; -# endif - -# if GNULIB_defined_ESTALE - case ESTALE: - msg = "Stale NFS file handle"; - break; -# endif - -# if GNULIB_defined_EDQUOT - case EDQUOT: - msg = "Disk quota exceeded"; - break; -# endif - -# if GNULIB_defined_ECANCELED - case ECANCELED: - msg = "Operation canceled"; - break; -# endif - } + char const *msg = strerror_override (errnum); if (msg) return safe_copy (buf, buflen, msg); } -#endif { int ret; diff --git a/modules/strerror b/modules/strerror index 0e7a254..804df27 100644 --- a/modules/strerror +++ b/modules/strerror @@ -3,15 +3,14 @@ strerror() function: return string describing error code. Files: lib/strerror.c -lib/strerror-impl.h m4/strerror.m4 Depends-on: string -errno [test $REPLACE_STRERROR = 1] -intprops [test $REPLACE_STRERROR = 1] -verify [test $REPLACE_STRERROR = 1] -strerror_r-posix [test $REPLACE_STRERROR = 1] +errno [test $REPLACE_STRERROR = 1] +intprops [test $REPLACE_STRERROR = 1] +strerror-override [test $REPLACE_STRERROR = 1] +verify [test $REPLACE_STRERROR = 1] configure.ac: gl_FUNC_STRERROR diff --git a/modules/strerror-override b/modules/strerror-override new file mode 100644 index 0000000..a31e8a1 --- /dev/null +++ b/modules/strerror-override @@ -0,0 +1,26 @@ +Description: +strerror_override() function: provide strings for gnulib-specific errno values + +Files: +lib/strerror-override.h +lib/strerror-override.c + +Depends-on: +errno + +configure.ac: +AC_REQUIRE([gl_HEADER_ERRNO_H]) +if test -n "$ERRNO_H"; then + AC_LIBOBJ([strerror-override]) +fi + +Makefile.am: + +Include: +"strerror-override.h" + +License: +LGPLv2+ + +Maintainer: +all diff --git a/modules/strerror_r-posix b/modules/strerror_r-posix index a36f2e6..3c80d79 100644 --- a/modules/strerror_r-posix +++ b/modules/strerror_r-posix @@ -10,6 +10,7 @@ string extensions errno [test $HAVE_DECL_STRERROR_R = 0 || test $REPLACE_STRERROR_R = 1] lock [test $HAVE_DECL_STRERROR_R = 0 || test $REPLACE_STRERROR_R = 1] +strerror-override [test $HAVE_DECL_STRERROR_R = 0 || test $REPLACE_STRERROR_R = 1] configure.ac: gl_FUNC_STRERROR_R -- 1.7.4.4