bug-gnulib
[Top][All Lists]
Advanced

[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);





reply via email to

[Prev in Thread] Current Thread [Next in Thread]