]> Savannah Git Hosting - gnulib.git/commitdiff
getaddrinfo: Support the AI_NUMERICSERV flag.
authorBruno Haible <bruno@clisp.org>
Wed, 12 Feb 2025 22:34:39 +0000 (23:34 +0100)
committerBruno Haible <bruno@clisp.org>
Wed, 12 Feb 2025 22:34:39 +0000 (23:34 +0100)
* m4/getaddrinfo.m4 (gl_GETADDRINFO): Require AC_CANONICAL_HOST. Test
whether getaddrinfo supports AI_NUMERICSERV.
* lib/getaddrinfo.c (getaddrinfo): Accept and implement the
AI_NUMERICSERV flag.
* tests/test-getaddrinfo.c (simple): In pass 4, pass the AI_NUMERICSERV
flag.
(main): Test numeric services in pass 1. Add pass 4.
* doc/posix-functions/getaddrinfo.texi: Mention the native Windows bug.

ChangeLog
doc/posix-functions/getaddrinfo.texi
lib/getaddrinfo.c
m4/getaddrinfo.m4
tests/test-getaddrinfo.c

index fec9aab6af5ff4aa060c936c15b9ed5e22052899..b5ca5b4041330c66385b8c2c6d25867927ad0f76 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2025-02-12  Bruno Haible  <bruno@clisp.org>
+
+       getaddrinfo: Support the AI_NUMERICSERV flag.
+       * m4/getaddrinfo.m4 (gl_GETADDRINFO): Require AC_CANONICAL_HOST. Test
+       whether getaddrinfo supports AI_NUMERICSERV.
+       * lib/getaddrinfo.c (getaddrinfo): Accept and implement the
+       AI_NUMERICSERV flag.
+       * tests/test-getaddrinfo.c (simple): In pass 4, pass the AI_NUMERICSERV
+       flag.
+       (main): Test numeric services in pass 1. Add pass 4.
+       * doc/posix-functions/getaddrinfo.texi: Mention the native Windows bug.
+
 2025-02-12  Bruno Haible  <bruno@clisp.org>
 
        getaddrinfo: Support the AI_NUMERICHOST flag.
index 4038bf7349f10d276ab3b518ff5d46d9190cac37..dd216d23d87d772942c15c574ecf9bacd774499d 100644 (file)
@@ -13,11 +13,14 @@ Portability problems fixed by Gnulib:
 This function is missing on some platforms:
 HP-UX 11.11, Cygwin 1.5.x, mingw, MSVC 14.
 @item
-On Windows, this function is declared in @code{<ws2tcpip.h>} rather than in
-@code{<netdb.h>}.
+On native Windows, this function is declared in @code{<ws2tcpip.h>}
+rather than in @code{<netdb.h>}.
 @item
-On Windows, in 32-bit mode, this function is defined with a calling convention
-that is different from @code{cdecl}.
+On native Windows, this function does not support
+the @code{AI_NUMERICSERV} hints flag.
+@item
+On native Windows, in 32-bit mode, this function is defined
+with a calling convention that is different from @code{cdecl}.
 @end itemize
 
 Portability problems not fixed by Gnulib:
index 4a0aeab9f12a328e1cd28d81c911cabef93deba5..a8c45c21c234d3ea47cc1553328c7564831eebee 100644 (file)
@@ -54,7 +54,7 @@
 
 #if HAVE_GETADDRINFO
 
-/* Override with cdecl calling convention.  */
+/* Override with cdecl calling convention and mingw fix.  */
 
 int
 getaddrinfo (const char *restrict nodename,
@@ -63,6 +63,10 @@ getaddrinfo (const char *restrict nodename,
              struct addrinfo **restrict res)
 # undef getaddrinfo
 {
+  if (hints && (hints->ai_flags & AI_NUMERICSERV) != 0
+      && servname && !(*servname >= '0' && *servname <= '9'))
+    return EAI_NONAME;
+
   return getaddrinfo (nodename, servname, hints, res);
 }
 
@@ -237,10 +241,17 @@ getaddrinfo (const char *restrict nodename,
 
 # ifdef WINDOWS_NATIVE
   if (use_win32_p ())
-    return getaddrinfo_ptr (nodename, servname, hints, res);
+    {
+      if (hints && (hints->ai_flags & AI_NUMERICSERV) != 0
+          && servname && !(*servname >= '0' && *servname <= '9'))
+        return EAI_NONAME;
+      return getaddrinfo_ptr (nodename, servname, hints, res);
+    }
 # endif
 
-  if (hints && (hints->ai_flags & ~(AI_CANONNAME|AI_PASSIVE|AI_NUMERICHOST)))
+  if (hints
+      && (hints->ai_flags
+          & ~(AI_CANONNAME | AI_PASSIVE | AI_NUMERICHOST | AI_NUMERICSERV)))
     /* FIXME: Support more flags. */
     return EAI_BADFLAGS;
 
index 1e1fc48a59760108c74a420086262df51af97171..19ae42cc157db019fd71fb40dc082e75d10fbaee 100644 (file)
@@ -1,5 +1,5 @@
 # getaddrinfo.m4
-# serial 35
+# serial 36
 dnl Copyright (C) 2004-2025 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -10,6 +10,7 @@ AC_DEFUN([gl_GETADDRINFO],
 [
   AC_REQUIRE([gl_SYS_SOCKET_H])dnl for HAVE_SYS_SOCKET_H, HAVE_WINSOCK2_H
   AC_REQUIRE([gl_NETDB_H])dnl for HAVE_NETDB_H
+  AC_REQUIRE([AC_CANONICAL_HOST])
   GETADDRINFO_LIB=
   gai_saved_LIBS="$LIBS"
 
@@ -88,6 +89,44 @@ int getaddrinfo (const char *, const char *, const struct addrinfo *, struct add
       HAVE_GETADDRINFO=0
     fi
   fi
+  AC_CACHE_CHECK([whether getaddrinfo supports AI_NUMERICSERV],
+    [gl_cv_func_getaddrinfo_works],
+    [AC_RUN_IFELSE(
+       [AC_LANG_PROGRAM([[
+#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>
+#include <string.h>
+          ]], [[
+          struct addrinfo hints;
+          struct addrinfo ai;
+          memset (&hints, 0, sizeof (hints));
+          hints.ai_flags = AI_NUMERICSERV;
+          return getaddrinfo ("www.gnu.org", "http", &hints, &ai) != EAI_NONAME;
+          ]])
+       ],
+       [gl_cv_func_getaddrinfo_works=yes],
+       [gl_cv_func_getaddrinfo_works=no],
+       [case "$host_os" in
+                             # Guess no on native Windows.
+          mingw* | windows*) gl_cv_func_getaddrinfo_works="guessing no" ;;
+                             # Guess yes otherwise.
+          *)                 gl_cv_func_getaddrinfo_works="guessing yes" ;;
+        esac
+       ])
+    ])
+  case "$gl_cv_func_getaddrinfo_works" in
+    *yes) ;;
+    *) REPLACE_GETADDRINFO=1 ;;
+  esac
   AC_DEFINE_UNQUOTED([HAVE_GETADDRINFO], [$HAVE_GETADDRINFO],
     [Define to 1 if getaddrinfo exists, or to 0 otherwise.])
 
index 8f35e6abc6c889e2610874f19dde90f5c3528552..31e999cb0e29c78e02ced6f32dfab04254bddc8c 100644 (file)
@@ -82,7 +82,9 @@ simple (int pass, char const *host, char const *service)
   else
     {
       memset (&hints, 0, sizeof (hints));
-      hints.ai_flags = AI_CANONNAME | (pass == 3 ? AI_NUMERICHOST : 0);
+      hints.ai_flags = AI_CANONNAME
+                       | (pass == 3 ? AI_NUMERICHOST : 0)
+                       | (pass == 4 ? AI_NUMERICSERV : 0);
       hints.ai_family = AF_UNSPEC;
       hints.ai_socktype = SOCK_STREAM;
       hints_p = &hints;
@@ -96,6 +98,9 @@ simple (int pass, char const *host, char const *service)
   if (pass == 3 && ! isdigit (host[0]))
     return res != EAI_NONAME;
 
+  if (pass == 4 && ! isdigit (service[0]))
+    return res != EAI_NONAME;
+
   if (res != 0)
     {
       /* EAI_AGAIN is returned if no network is available. Don't fail
@@ -187,9 +192,13 @@ int main (void)
   (void) gl_sockets_startup (SOCKETS_1_1);
 
   return (  simple (1, HOST1, SERV1)
+          + simple (1, HOST1, "80")
           + simple (1, HOST2, SERV2)
+          + simple (1, HOST2, "443")
           + simple (1, HOST3, SERV3)
+          + simple (1, HOST3, "80")
           + simple (1, HOST4, SERV4)
+          + simple (1, HOST4, "389")
           + simple (2, HOST1, SERV1)
           + simple (2, HOST2, SERV2)
           + simple (2, HOST3, SERV3)
@@ -203,5 +212,13 @@ int main (void)
           + simple (3, HOST1, SERV1)
           + simple (3, HOST2, SERV2)
           + simple (3, HOST3, SERV3)
-          + simple (3, HOST4, SERV4));
+          + simple (3, HOST4, SERV4)
+          + simple (4, HOST1, SERV1)
+          + simple (4, HOST1, "80")
+          + simple (4, HOST2, SERV2)
+          + simple (4, HOST2, "443")
+          + simple (4, HOST3, SERV3)
+          + simple (4, HOST3, "80")
+          + simple (4, HOST4, SERV4)
+          + simple (4, HOST4, "389"));
 }