getaddrinfo: fix gai_strerror signature
authorEric Blake <eblake@redhat.com>
Thu, 28 Apr 2011 22:46:16 +0000 (16:46 -0600)
committerEric Blake <eblake@redhat.com>
Thu, 28 Apr 2011 23:35:16 +0000 (17:35 -0600)
Several platforms declare gai_strerror to return char* rather than
const char*.  Worse, on mingw, if UNICODE is defined, it is defined
to return WCHAR*, which means the result is in unicode but an
application expecting bytes for characters will only see a one-byte
answer.

* m4/getaddrinfo.m4 (gl_GETADDRINFO): Detect broken signatures,
and work around mingw with UNICODE defined.
(gl_PREREQ_GETADDRINFO): Drop redundant decl check.
* m4/netdb_h.m4 (gl_NETDB_H_DEFAULTS): Add witness.
* modules/netdb (Makefile.am): Substitute it.
* lib/netdb.in.h (gai_strerror): Declare replacement.
* lib/gai_strerror.c (rpl_gai_strerror): Fix signature.
* doc/posix-functions/gai_strerror.texi (gai_strerror): Document
the fix.

Signed-off-by: Eric Blake <eblake@redhat.com>
ChangeLog
doc/posix-functions/gai_strerror.texi
lib/gai_strerror.c
lib/netdb.in.h
m4/getaddrinfo.m4
m4/netdb_h.m4
modules/netdb

index 6b755c147019e529b71c99e9c0b4c3e7c3b00f68..9e5aa41558003199e34931d7576369e67eb2b15d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
 2011-04-28  Eric Blake  <eblake@redhat.com>
 
+       getaddrinfo: fix gai_strerror signature
+       * m4/getaddrinfo.m4 (gl_GETADDRINFO): Detect broken signatures,
+       and work around mingw with UNICODE defined.
+       (gl_PREREQ_GETADDRINFO): Drop redundant decl check.
+       * m4/netdb_h.m4 (gl_NETDB_H_DEFAULTS): Add witness.
+       * modules/netdb (Makefile.am): Substitute it.
+       * lib/netdb.in.h (gai_strerror): Declare replacement.
+       * lib/gai_strerror.c (rpl_gai_strerror): Fix signature.
+       * doc/posix-functions/gai_strerror.texi (gai_strerror): Document
+       the fix.
+
        getsockopt: avoid compiler warning
        * lib/getsockopt.c (rpl_getsockopt): Add a cast for mingw.
        Reported by Matthias Bolte.
index ece2bdc99176ab8d036f4eb9e486f3841bb56f86..d94a6ed9bd30460b64fd59c11f2e5edf26358c82 100644 (file)
@@ -10,13 +10,18 @@ Portability problems fixed by Gnulib:
 @itemize
 @item
 This function is missing on some platforms:
-HP-UX 11.11, IRIX 6.5, OSF/1 4.0, Solaris 7, Cygwin 1.5.x, mingw, Interix 3.5, BeOS.
+HP-UX 11.11, IRIX 6.5, OSF/1 4.0, Solaris 7, Cygwin 1.5.x, Interix
+3.5, BeOS.
+@item
+This function is only available in @code{<ws2tcpip.h>} on some
+platforms:
+mingw.
+@item
+This function's return type is @code{char *} instead of @code{const char *}
+on some platforms:
+AIX 7.1, HP-UX 11, OSF/1 5.1, Solaris 9, mingw.
 @end itemize
 
 Portability problems not fixed by Gnulib:
 @itemize
-@item
-This function's return type is @code{char *} instead of @code{const char *}
-on some platforms:
-AIX 7.1, HP-UX 11, OSF/1 5.1, Solaris 9.
 @end itemize
index ee595e1a7e70172d16eb197323a22f40f7ac8f30..f758f8e90913c94598bc4e42ae30b84c42a62d34 100644 (file)
 # define N_(String) String
 #endif
 
+#if HAVE_DECL_GAI_STRERROR
+
+# include <sys/socket.h>
+# undef gai_strerror
+# if HAVE_DECL_GAI_STRERRORA
+#  define gai_strerror gai_strerrorA
+# endif
+
+const char *
+rpl_gai_strerror (int code)
+{
+  return gai_strerror (code);
+}
+
+#else /* !HAVE_DECL_GAI_STRERROR */
+
 static struct
   {
     int code;
@@ -71,6 +87,7 @@ gai_strerror (int code)
 
   return _("Unknown error");
 }
-#ifdef _LIBC
+# ifdef _LIBC
 libc_hidden_def (gai_strerror)
-#endif
+# endif
+#endif /* !HAVE_DECL_GAI_STRERROR */
index d789e34224ea64f701c91317e968607ab306d336..64cd9ac53bdab0e45a03e3bde3680be439dea2af 100644 (file)
@@ -167,12 +167,23 @@ extern int getaddrinfo (const char *restrict nodename,
 extern void freeaddrinfo (struct addrinfo *ai) _GL_ARG_NONNULL ((1));
 # endif
 
-# if !@HAVE_DECL_GAI_STRERROR@
+# if @REPLACE_GAI_STRERROR@
+#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+#   undef gai_strerror
+#   define gai_strerror rpl_gai_strerror
+#  endif
+_GL_FUNCDECL_RPL (gai_strerror, const char *, (int ecode));
+_GL_CXXALIAS_RPL (gai_strerror, const char *, (int ecode));
+# else
+#  if !@HAVE_DECL_GAI_STRERROR@
 /* Convert error return from getaddrinfo() to a string.
    For more details, see the POSIX:2001 specification
    <http://www.opengroup.org/susv3xsh/gai_strerror.html>.  */
-extern const char *gai_strerror (int ecode);
+_GL_FUNCDECL_SYS (gai_strerror, const char *, (int ecode));
+#  endif
+_GL_CXXALIAS_SYS (gai_strerror, const char *, (int ecode));
 # endif
+_GL_CXXALIASWARN (gai_strerror);
 
 # if !@HAVE_DECL_GETNAMEINFO@
 /* Convert socket address to printable node and service names.
index e57623694cc43ae9af91e859fe0f93c7dc348847..f29e90398744fb6d750a22f2a5f172efaaa0b792 100644 (file)
@@ -1,4 +1,4 @@
-# getaddrinfo.m4 serial 24
+# getaddrinfo.m4 serial 25
 dnl Copyright (C) 2004-2011 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -62,9 +62,7 @@ AC_DEFUN([gl_GETADDRINFO],
   # We can't use AC_REPLACE_FUNCS here because gai_strerror may be an
   # inline function declared in ws2tcpip.h, so we need to get that
   # header included somehow.
-  AC_CACHE_CHECK([for gai_strerror (possibly via ws2tcpip.h)],
-    gl_cv_func_gai_strerror, [
-      AC_LINK_IFELSE([AC_LANG_PROGRAM([[
+  AC_CHECK_DECLS([gai_strerror, gai_strerrorA], [], [break], [[
 #include <sys/types.h>
 #ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
@@ -76,11 +74,32 @@ AC_DEFUN([gl_GETADDRINFO],
 #include <ws2tcpip.h>
 #endif
 #include <stddef.h>
-]], [[gai_strerror (NULL);]])],
-        [gl_cv_func_gai_strerror=yes],
-        [gl_cv_func_gai_strerror=no])])
-  if test $gl_cv_func_gai_strerror = no; then
+]])
+  if test $ac_cv_have_decl_gai_strerror = no; then
     AC_LIBOBJ([gai_strerror])
+  else
+    dnl check for correct signature
+    AC_CACHE_CHECK([for gai_strerror with POSIX signature],
+     [gl_cv_func_gai_strerror_posix_signature], [
+      AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
+#include <sys/types.h>
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_WS2TCPIP_H
+#include <ws2tcpip.h>
+#endif
+#include <stddef.h>
+extern const char *gai_strerror(int);]])],
+        [gl_cv_func_gai_strerror_posix_signature=yes],
+        [gl_cv_func_gai_strerror_posix_signature=no])])
+    if test $gl_cv_func_gai_strerror_posix_signature = no; then
+      REPLACE_GAI_STRERROR=1
+      AC_LIBOBJ([gai_strerror])
+    fi
   fi
 
   LIBS="$gai_saved_LIBS"
@@ -112,7 +131,7 @@ AC_DEFUN([gl_PREREQ_GETADDRINFO], [
 
   AC_CHECK_HEADERS_ONCE([netinet/in.h])
 
-  AC_CHECK_DECLS([getaddrinfo, freeaddrinfo, gai_strerror, getnameinfo],,,[
+  AC_CHECK_DECLS([getaddrinfo, freeaddrinfo, getnameinfo],,,[
   /* sys/types.h is not needed according to POSIX, but the
      sys/socket.h in i386-unknown-freebsd4.10 and
      powerpc-apple-darwin5.5 required it. */
index 9a01cd6a76a9724651f83bfbb6347bd19050d26a..259c7a3181d4f138ee0590655d84de9e3aa953aa 100644 (file)
@@ -37,4 +37,5 @@ AC_DEFUN([gl_NETDB_H_DEFAULTS],
   HAVE_DECL_GAI_STRERROR=1; AC_SUBST([HAVE_DECL_GAI_STRERROR])
   HAVE_DECL_GETADDRINFO=1;  AC_SUBST([HAVE_DECL_GETADDRINFO])
   HAVE_DECL_GETNAMEINFO=1;  AC_SUBST([HAVE_DECL_GETNAMEINFO])
+  REPLACE_GAI_STRERROR=0;   AC_SUBST([REPLACE_GAI_STRERROR])
 ])
index 97c40bcce31da583ae7b06cb92fde3e3e8870291..8d210c949ec08e31d31ad6519502d5b6884ac328 100644 (file)
@@ -33,6 +33,7 @@ netdb.h: netdb.in.h $(top_builddir)/config.status $(ARG_NONNULL_H) $(WARN_ON_USE
              -e 's|@''HAVE_DECL_GAI_STRERROR''@|$(HAVE_DECL_GAI_STRERROR)|g' \
              -e 's|@''HAVE_DECL_GETADDRINFO''@|$(HAVE_DECL_GETADDRINFO)|g' \
              -e 's|@''HAVE_DECL_GETNAMEINFO''@|$(HAVE_DECL_GETNAMEINFO)|g' \
+             -e 's|@''REPLACE_GAI_STRERROR''@|$(REPLACE_GAI_STRERROR)|g' \
              -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
              -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
              < $(srcdir)/netdb.in.h; \