While testing coreutils on Solaris 10, I see a test failure:

FAIL: test-getaddrinfo
======================

Test case pass=3, host=www.gnu.org, service=http failed: expected EAI_NONAME, 
got 9
Test case pass=3, host=www.ibm.com, service=https failed: expected EAI_NONAME, 
got 9
Test case pass=3, host=microsoft.com, service=http failed: expected EAI_NONAME, 
got 9
FAIL test-getaddrinfo (exit status: 3)

The return value 9 is EAI_SERVICE, where EAI_NONAME is expected.


This patch fixes it.


2026-01-23  Bruno Haible  <[email protected]>

        getaddrinfo: Fix test failure on Solaris 10.
        * m4/getaddrinfo.m4 (gl_GETADDRINFO): Test also whether getaddrinfo
        supports AI_NUMERICHOST.
        * lib/getaddrinfo.c (is_numeric_host): Define also on Solaris.
        (getaddrinfo): Add a workaround for Solaris 10.
        * doc/posix-functions/getaddrinfo.texi: Mention the Solaris 10 bug.

diff --git a/doc/posix-functions/getaddrinfo.texi 
b/doc/posix-functions/getaddrinfo.texi
index dd216d23d8..7b9479d013 100644
--- a/doc/posix-functions/getaddrinfo.texi
+++ b/doc/posix-functions/getaddrinfo.texi
@@ -21,6 +21,9 @@
 @item
 On native Windows, in 32-bit mode, this function is defined
 with a calling convention that is different from @code{cdecl}.
+@item
+On Solaris 10, this function does not support
+the @code{AI_NUMERICHOST} hints flag.
 @end itemize
 
 Portability problems not fixed by Gnulib:
diff --git a/lib/getaddrinfo.c b/lib/getaddrinfo.c
index b497aa3e2d..2b60377bdb 100644
--- a/lib/getaddrinfo.c
+++ b/lib/getaddrinfo.c
@@ -52,9 +52,40 @@
 # define PF_UNSPEC 0
 #endif
 
+#if defined __sun || !HAVE_GETADDRINFO
+
+static bool
+is_numeric_host (const char *host, int family)
+{
+# if HAVE_IPV4
+  if (family == PF_INET || family == PF_UNSPEC)
+    {
+      /* glibc supports IPv4 addresses in numbers-and-dots notation, that is,
+         also hexadecimal and octal number formats and formats that don't
+         require all four bytes to be explicitly written, via inet_aton().
+         But POSIX doesn't require support for these legacy formats.  Therefore
+         we are free to use inet_pton() instead of inet_aton().  */
+      struct in_addr addr;
+      if (inet_pton (AF_INET, host, &addr))
+        return true;
+    }
+# endif
+# if HAVE_IPV6
+  if (family == PF_INET6 || family == PF_UNSPEC)
+    {
+      struct in6_addr addr;
+      if (inet_pton (AF_INET6, host, &addr))
+        return true;
+    }
+# endif
+  return false;
+}
+
+#endif
+
 #if HAVE_GETADDRINFO
 
-/* Override with cdecl calling convention and mingw fix.  */
+/* Override with cdecl calling convention and Windows and Solaris 10 fixes.  */
 
 int
 getaddrinfo (const char *restrict nodename,
@@ -63,10 +94,18 @@ getaddrinfo (const char *restrict nodename,
              struct addrinfo **restrict res)
 # undef getaddrinfo
 {
+  /* Workaround for native Windows.  */
   if (hints && (hints->ai_flags & AI_NUMERICSERV) != 0
       && servname && !(*servname >= '0' && *servname <= '9'))
     return EAI_NONAME;
 
+# ifdef __sun
+  /* Workaround for Solaris 10.  */
+  if (hints && (hints->ai_flags & AI_NUMERICHOST)
+      && nodename && !is_numeric_host (nodename, hints->ai_family))
+    return EAI_NONAME;
+# endif
+
   return getaddrinfo (nodename, servname, hints, res);
 }
 
@@ -184,33 +223,6 @@ validate_family (int family)
    return false;
 }
 
-static bool
-is_numeric_host (const char *host, int family)
-{
-# if HAVE_IPV4
-  if (family == PF_INET || family == PF_UNSPEC)
-    {
-      /* glibc supports IPv4 addresses in numbers-and-dots notation, that is,
-         also hexadecimal and octal number formats and formats that don't
-         require all four bytes to be explicitly written, via inet_aton().
-         But POSIX doesn't require support for these legacy formats.  Therefore
-         we are free to use inet_pton() instead of inet_aton().  */
-      struct in_addr addr;
-      if (inet_pton (AF_INET, host, &addr))
-        return true;
-    }
-# endif
-# if HAVE_IPV6
-  if (family == PF_INET6 || family == PF_UNSPEC)
-    {
-      struct in6_addr addr;
-      if (inet_pton (AF_INET6, host, &addr))
-        return true;
-    }
-# endif
-  return false;
-}
-
 /* Translate name of a service location and/or a service name to set of
    socket addresses. */
 int
diff --git a/m4/getaddrinfo.m4 b/m4/getaddrinfo.m4
index 20363bf743..8a63600b83 100644
--- a/m4/getaddrinfo.m4
+++ b/m4/getaddrinfo.m4
@@ -1,5 +1,5 @@
 # getaddrinfo.m4
-# serial 38
+# serial 39
 dnl Copyright (C) 2004-2026 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -90,7 +90,7 @@ AC_DEFUN([gl_GETADDRINFO]
     fi
   fi
   if test $HAVE_GETADDRINFO != 0; then
-    AC_CACHE_CHECK([whether getaddrinfo supports AI_NUMERICSERV],
+    AC_CACHE_CHECK([whether getaddrinfo supports AI_NUMERICHOST and 
AI_NUMERICSERV],
       [gl_cv_func_getaddrinfo_works],
       [AC_RUN_IFELSE(
          [AC_LANG_PROGRAM([[
@@ -107,16 +107,30 @@ AC_DEFUN([gl_GETADDRINFO]
 #include <stddef.h>
 #include <string.h>
             ]], [[
-              struct addrinfo hints;
+              int result = 0;
               struct addrinfo *ai;
-              memset (&hints, 0, sizeof (hints));
-              hints.ai_flags = AI_NUMERICSERV;
-              return getaddrinfo ("www.gnu.org", "http", &hints, &ai) != 
EAI_NONAME;
+              {
+                struct addrinfo hints;
+                memset (&hints, 0, sizeof (hints));
+                hints.ai_flags = AI_NUMERICHOST;
+                if (getaddrinfo ("www.gnu.org", "http", &hints, &ai) != 
EAI_NONAME)
+                  result |= 1;
+              }
+              {
+                struct addrinfo hints;
+                memset (&hints, 0, sizeof (hints));
+                hints.ai_flags = AI_NUMERICSERV;
+                if (getaddrinfo ("www.gnu.org", "http", &hints, &ai) != 
EAI_NONAME)
+                  result |= 2;
+              }
+              return result;
             ]])
          ],
          [gl_cv_func_getaddrinfo_works=yes],
          [gl_cv_func_getaddrinfo_works=no],
          [case "$host_os" in
+                               # Guess no on Solaris.
+            solaris*)          gl_cv_func_getaddrinfo_works="guessing no" ;;
                                # Guess no on native Windows.
             mingw* | windows*) gl_cv_func_getaddrinfo_works="guessing no" ;;
                                # Guess yes otherwise.




Reply via email to