bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] getaddrinfo: fix gai_strerror signature


From: Eric Blake
Subject: [PATCH] getaddrinfo: fix gai_strerror signature
Date: Thu, 28 Apr 2011 17:34:42 -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.

Signed-off-by: Eric Blake <address@hidden>
---

Tested on Solaris 9, mingw, and HP-UX 11.11 to prevent the
warning/error in test-getaddrinfo.

 ChangeLog                             |   12 ++++++++++
 doc/posix-functions/gai_strerror.texi |   15 +++++++++----
 lib/gai_strerror.c                    |   21 +++++++++++++++++-
 lib/netdb.in.h                        |   15 +++++++++++-
 m4/getaddrinfo.m4                     |   37 +++++++++++++++++++++++++--------
 m4/netdb_h.m4                         |    1 +
 modules/netdb                         |    1 +
 7 files changed, 84 insertions(+), 18 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 6b755c1..34e635b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
 2011-04-28  Eric Blake  <address@hidden>

+       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.
diff --git a/doc/posix-functions/gai_strerror.texi 
b/doc/posix-functions/gai_strerror.texi
index ece2bdc..d94a6ed 100644
--- a/doc/posix-functions/gai_strerror.texi
+++ b/doc/posix-functions/gai_strerror.texi
@@ -10,13 +10,18 @@ gai_strerror
 @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.
address@hidden
+This function is only available in @code{<ws2tcpip.h>} on some
+platforms:
+mingw.
address@hidden
+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
address@hidden
-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
diff --git a/lib/gai_strerror.c b/lib/gai_strerror.c
index ee595e1..f758f8e 100644
--- a/lib/gai_strerror.c
+++ b/lib/gai_strerror.c
@@ -32,6 +32,22 @@
 # 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 */
diff --git a/lib/netdb.in.h b/lib/netdb.in.h
index d789e34..64cd9ac 100644
--- a/lib/netdb.in.h
+++ b/lib/netdb.in.h
@@ -167,12 +167,23 @@ extern int getaddrinfo (const char *restrict nodename,
 extern void freeaddrinfo (struct addrinfo *ai) _GL_ARG_NONNULL ((1));
 # endif

-# if address@hidden@
+# 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 address@hidden@
 /* 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 address@hidden@
 /* Convert socket address to printable node and service names.
diff --git a/m4/getaddrinfo.m4 b/m4/getaddrinfo.m4
index e576236..f29e903 100644
--- a/m4/getaddrinfo.m4
+++ b/m4/getaddrinfo.m4
@@ -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. */
diff --git a/m4/netdb_h.m4 b/m4/netdb_h.m4
index 9a01cd6..259c7a3 100644
--- a/m4/netdb_h.m4
+++ b/m4/netdb_h.m4
@@ -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])
 ])
diff --git a/modules/netdb b/modules/netdb
index 97c40bc..8d210c9 100644
--- a/modules/netdb
+++ b/modules/netdb
@@ -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; \
-- 
1.7.4.4




reply via email to

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