[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: new module 'errno'
From: |
Bruno Haible |
Subject: |
Re: new module 'errno' |
Date: |
Sun, 14 Sep 2008 04:19:32 +0200 |
User-agent: |
KMail/1.5.4 |
> With this, the conversion function from a WSAGetLastError() value to an
> errno value is
> e -> (e < 10025 ? e - 10000 :
> e == WSAENAMETOOLONG ? ENAMETOOLONG :
> e == WSAENOTEMPTY ; ENOTEMPTY :
> e);
That's still not enough. Looking at [1], I think it should also map
WSA_INVALID_HANDLE -> EBADF
WSA_NOT_ENOUGH_MEMORY -> ENOMEM
WSA_INVALID_PARAMETER -> EINVAL
[1] http://msdn.microsoft.com/en-us/library/ms740668(VS.85).aspx
I'm extending the strerror function to cover these E* and WSAE* values.
2008-09-13 Bruno Haible <address@hidden>
Extend strerror to cover the added errno values.
* lib/strerror.c: Include errno.h and winsock2.h if it exists.
(rpl_strerror): Provide error messages for the added errno values and
for the WSA* values.
* m4/strerror.m4 (gl_FUNC_STRERROR): Test REPLACE_STRERROR.
(gl_FUNC_STRERROR_SEPARATE): If errno.h is replaced, always replace
strerror.
(gl_PREREQ_STRERROR): Test whether winsock2.h exists.
* modules/strerror (Depends-on): Add errno.
* doc/posix-functions/strerror.texi: Document the change.
* tests/test-strerror.c (main): Check also the string for ETIMEDOUT
and EOVERFLOW.
*** doc/posix-functions/strerror.texi.orig 2008-09-14 04:10:20.000000000
+0200
--- doc/posix-functions/strerror.texi 2008-09-14 01:13:45.000000000 +0200
***************
*** 10,16 ****
@itemize
@item
This function is missing on some old platforms.
!
@item
This function fails to return a string for out-of-range integers on
some platforms:
--- 10,19 ----
@itemize
@item
This function is missing on some old platforms.
! @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 4.0, mingw.
@item
This function fails to return a string for out-of-range integers on
some platforms:
*** lib/strerror.c.orig 2008-09-14 04:10:20.000000000 +0200
--- lib/strerror.c 2008-09-14 04:07:28.000000000 +0200
***************
*** 1,6 ****
/* strerror.c --- POSIX compatible system error routine
! Copyright (C) 2007 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
--- 1,6 ----
/* strerror.c --- POSIX compatible system error routine
! Copyright (C) 2007-2008 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
***************
*** 21,28 ****
--- 21,35 ----
#if REPLACE_STRERROR
+ # include <errno.h>
# include <stdio.h>
+ # if GNULIB_defined_ESOCK /* native Windows platforms */
+ # if HAVE_WINSOCK2_H
+ # include <winsock2.h>
+ # endif
+ # endif
+
# include "intprops.h"
# undef strerror
***************
*** 33,49 ****
char *
rpl_strerror (int n)
{
! char *result = strerror (n);
!
! if (result == NULL || result[0] == '\0')
{
! static char const fmt[] = "Unknown error (%d)";
! static char mesg[sizeof fmt + INT_STRLEN_BOUND (n)];
! sprintf (mesg, fmt, n);
! return mesg;
}
! return result;
}
#endif
--- 40,274 ----
char *
rpl_strerror (int n)
{
! /* These error messages are taken from glibc/sysdeps/gnu/errlist.c. */
! switch (n)
{
! # if GNULIB_defined_ETXTBSY
! case ETXTBSY:
! return "Text file busy";
! # endif
!
! # if GNULIB_defined_ESOCK /* native Windows platforms */
! case EWOULDBLOCK:
! return "Operation would block";
! case EINPROGRESS:
! return "Operation now in progress";
! case EALREADY:
! return "Operation already in progress";
! case ENOTSOCK:
! return "Socket operation on non-socket";
! case EDESTADDRREQ:
! return "Destination address required";
! case EMSGSIZE:
! return "Message too long";
! case EPROTOTYPE:
! return "Protocol wrong type for socket";
! case ENOPROTOOPT:
! return "Protocol not available";
! case EPROTONOSUPPORT:
! return "Protocol not supported";
! case ESOCKTNOSUPPORT:
! return "Socket type not supported";
! case EOPNOTSUPP:
! return "Operation not supported";
! case EPFNOSUPPORT:
! return "Protocol family not supported";
! case EAFNOSUPPORT:
! return "Address family not supported by protocol";
! case EADDRINUSE:
! return "Address already in use";
! case EADDRNOTAVAIL:
! return "Cannot assign requested address";
! case ENETDOWN:
! return "Network is down";
! case ENETUNREACH:
! return "Network is unreachable";
! case ENETRESET:
! return "Network dropped connection on reset";
! case ECONNABORTED:
! return "Software caused connection abort";
! case ECONNRESET:
! return "Connection reset by peer";
! case ENOBUFS:
! return "No buffer space available";
! case EISCONN:
! return "Transport endpoint is already connected";
! case ENOTCONN:
! return "Transport endpoint is not connected";
! case ESHUTDOWN:
! return "Cannot send after transport endpoint shutdown";
! case ETOOMANYREFS:
! return "Too many references: cannot splice";
! case ETIMEDOUT:
! return "Connection timed out";
! case ECONNREFUSED:
! return "Connection refused";
! case ELOOP:
! return "Too many levels of symbolic links";
! case EHOSTDOWN:
! return "Host is down";
! case EHOSTUNREACH:
! return "No route to host";
! case EPROCLIM:
! return "Too many processes";
! case EUSERS:
! return "Too many users";
! case EDQUOT:
! return "Disk quota exceeded";
! case ESTALE:
! return "Stale NFS file handle";
! case EREMOTE:
! return "Object is remote";
! # 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:
! return "Overlapped operation aborted";
! case WSA_IO_INCOMPLETE:
! return "Overlapped I/O event object not in signaled state";
! case WSA_IO_PENDING:
! return "Overlapped operations will complete later";
! /* WSAEINTR maps to EINTR */
! /* WSAEBADF maps to EBADF */
! /* WSAEACCES maps to EACCES */
! /* WSAEFAULT maps to EFAULT */
! /* WSAEINVAL maps to EINVAL */
! /* WSAEMFILE maos to EMFILE */
! /* WSAEWOULDBLOCK is 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:
! return "Network subsystem is unavailable";
! case WSAVERNOTSUPPORTED:
! return "Winsock.dll version out of range";
! case WSANOTINITIALISED:
! return "Successful WSAStartup not yet performed";
! case WSAEDISCON:
! return "Graceful shutdown in progress";
! case WSAENOMORE: case WSA_E_NO_MORE:
! return "No more results";
! case WSAECANCELLED: case WSA_E_CANCELLED:
! return "Call was canceled";
! case WSAEINVALIDPROCTABLE:
! return "Procedure call table is invalid";
! case WSAEINVALIDPROVIDER:
! return "Service provider is invalid";
! case WSAEPROVIDERFAILEDINIT:
! return "Service provider failed to initialize";
! case WSASYSCALLFAILURE:
! return "System call failure";
! case WSASERVICE_NOT_FOUND:
! return "Service not found";
! case WSATYPE_NOT_FOUND:
! return "Class type not found";
! case WSAEREFUSED:
! return "Database query was refused";
! case WSAHOST_NOT_FOUND:
! return "Host not found";
! case WSATRY_AGAIN:
! return "Nonauthoritative host not found";
! case WSANO_RECOVERY:
! return "Nonrecoverable error";
! case WSANO_DATA:
! return "Valid name, no data record of requested type";
! /* WSA_QOS_* omitted */
! # endif
! # endif
!
! # if GNULIB_defined_ENOMSG
! case ENOMSG:
! return "No message of desired type";
! # endif
!
! # if GNULIB_defined_EIDRM
! case EIDRM:
! return "Identifier removed";
! # endif
!
! # if GNULIB_defined_ENOLINK
! case ENOLINK:
! return "Link has been severed";
! # endif
!
! # if GNULIB_defined_EPROTO
! case EPROTO:
! return "Protocol error";
! # endif
!
! # if GNULIB_defined_EMULTIHOP
! case EMULTIHOP:
! return "Multihop attempted";
! # endif
!
! # if GNULIB_defined_EBADMSG
! case EBADMSG:
! return "Bad message";
! # endif
!
! # if GNULIB_defined_EOVERFLOW
! case EOVERFLOW:
! return "Value too large for defined data type";
! # endif
!
! # if GNULIB_defined_ENOTSUP
! case ENOTSUP:
! return "Not supported";
! # endif
!
! # if GNULIB_defined_
! case ECANCELED:
! return "Operation canceled";
! # endif
}
! {
! char *result = strerror (n);
!
! if (result == NULL || result[0] == '\0')
! {
! static char const fmt[] = "Unknown error (%d)";
! static char mesg[sizeof fmt + INT_STRLEN_BOUND (n)];
! sprintf (mesg, fmt, n);
! return mesg;
! }
!
! return result;
! }
}
#endif
*** m4/strerror.m4.orig 2008-09-14 04:10:20.000000000 +0200
--- m4/strerror.m4 2008-09-14 04:00:52.000000000 +0200
***************
*** 1,4 ****
! # strerror.m4 serial 8
dnl Copyright (C) 2002, 2007-2008 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
--- 1,4 ----
! # strerror.m4 serial 9
dnl Copyright (C) 2002, 2007-2008 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
***************
*** 7,13 ****
AC_DEFUN([gl_FUNC_STRERROR],
[
AC_REQUIRE([gl_FUNC_STRERROR_SEPARATE])
! if test $gl_cv_func_working_strerror = no; then
AC_LIBOBJ([strerror])
AC_DEFINE_UNQUOTED([REPLACE_STRERROR], [$REPLACE_STRERROR],
[Define this to 1 if strerror is broken.])
--- 7,13 ----
AC_DEFUN([gl_FUNC_STRERROR],
[
AC_REQUIRE([gl_FUNC_STRERROR_SEPARATE])
! if test $REPLACE_STRERROR = 1; then
AC_LIBOBJ([strerror])
AC_DEFINE_UNQUOTED([REPLACE_STRERROR], [$REPLACE_STRERROR],
[Define this to 1 if strerror is broken.])
***************
*** 18,42 ****
AC_DEFUN([gl_FUNC_STRERROR_SEPARATE],
[
AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
! AC_CACHE_CHECK([for working strerror function],
! [gl_cv_func_working_strerror],
! [AC_RUN_IFELSE(
! [AC_LANG_PROGRAM(
! [[#include <string.h>
! ]],
! [[return !*strerror (-2);]])],
! [gl_cv_func_working_strerror=yes],
! [gl_cv_func_working_strerror=no],
! [dnl Assume crossbuild works if it compiles.
! AC_COMPILE_IFELSE(
! [AC_LANG_PROGRAM(
! [[#include <string.h>
! ]],
! [[return !*strerror (-2);]])],
! [gl_cv_func_working_strerror=yes],
! [gl_cv_func_working_strerror=no])])])
! if test $gl_cv_func_working_strerror = no ; then
REPLACE_STRERROR=1
gl_PREREQ_STRERROR
fi
])
--- 18,55 ----
AC_DEFUN([gl_FUNC_STRERROR_SEPARATE],
[
AC_REQUIRE([gl_HEADER_STRING_H_DEFAULTS])
! AC_REQUIRE([gl_HEADER_ERRNO_H])
! if test -z "$ERRNO_H"; then
! AC_CACHE_CHECK([for working strerror function],
! [gl_cv_func_working_strerror],
! [AC_RUN_IFELSE(
! [AC_LANG_PROGRAM(
! [[#include <string.h>
! ]],
! [[return !*strerror (-2);]])],
! [gl_cv_func_working_strerror=yes],
! [gl_cv_func_working_strerror=no],
! [dnl Assume crossbuild works if it compiles.
! AC_COMPILE_IFELSE(
! [AC_LANG_PROGRAM(
! [[#include <string.h>
! ]],
! [[return !*strerror (-2);]])],
! [gl_cv_func_working_strerror=yes],
! [gl_cv_func_working_strerror=no])
! ])
! ])
! if test $gl_cv_func_working_strerror = no; then
! dnl The system's strerror() fails to return a string for out-of-range
! dnl integers. Replace it.
! REPLACE_STRERROR=1
! fi
! else
! dnl The system's strerror() cannot know about the new errno values we add
! dnl to <errno.h>. Replace it.
REPLACE_STRERROR=1
+ fi
+ if test $REPLACE_STRERROR = 1; then
gl_PREREQ_STRERROR
fi
])
***************
*** 44,47 ****
--- 57,68 ----
# Prerequisites of lib/strerror.c.
AC_DEFUN([gl_PREREQ_STRERROR], [
AC_CHECK_DECLS([strerror])
+ AC_CHECK_HEADERS_ONCE([sys/socket.h])
+ if test $ac_cv_header_sys_socket_h != yes; then
+ dnl We cannot use AC_CHECK_HEADERS_ONCE here, because that would make
+ dnl the check for those headers unconditional; yet cygwin reports
+ dnl that the headers are present but cannot be compiled (since on
+ dnl cygwin, all socket information should come from sys/socket.h).
+ AC_CHECK_HEADERS([winsock2.h])
+ fi
])
*** modules/strerror.orig 2008-09-14 04:10:20.000000000 +0200
--- modules/strerror 2008-09-14 02:00:21.000000000 +0200
***************
*** 6,11 ****
--- 6,12 ----
m4/strerror.m4
Depends-on:
+ errno
intprops
string
*** tests/test-strerror.c.orig 2008-09-14 04:10:20.000000000 +0200
--- tests/test-strerror.c 2008-09-14 01:15:18.000000000 +0200
***************
*** 40,49 ****
--- 40,58 ----
main (int argc, char **argv)
{
char *str;
+
str = strerror (EACCES);
ASSERT (str);
ASSERT (*str);
+ str = strerror (ETIMEDOUT);
+ ASSERT (str);
+ ASSERT (*str);
+
+ str = strerror (EOVERFLOW);
+ ASSERT (str);
+ ASSERT (*str);
+
str = strerror (0);
ASSERT (str);
ASSERT (*str);
Re: new module 'errno', Eric Blake, 2008/09/15