Hi/2.

Bruno Haible wrote:
> KO Myung-Hun wrote:
>> These are the patches to support AI_NUMERICSERV and AI_NUMERICHOST flag
>> to getaddrinfo().
>>
>> Review, please...
>>
>> [PATCH 1/2] getaddrinfo: Add AI_NUMERICSERV to the supported flags
>> [PATCH 2/2] getaddrinfo: Add AI_NUMERICHOST flag support
> 
> Your patches don't contain actual portable support for these flags
> (on platforms where the native function does not implement it).
> 
> POSIX [1] specifies the meaning of these two flags. So, if you encountered
> a program which uses them, that is OK and I have no objection to Gnulib
> supporting them.
> 
> But the way to do so is in several steps, for each of the flags:
>   1) Prepare a patch to tests/test-getaddrinfo.c that verifies the behaviour
>      of the flag.
>   2) Send us this patch, so that we can run the modified test on many
>      platforms (including native Windows).
>      Also, run the modified test yourself, on OS/2.
>   3) Then it will be clear which parts of lib/getaddrinfo.c need to be 
> extended.
> 
> Bruno
> 
> [1] 
> https://pubs.opengroup.org/onlinepubs/9799919799/functions/getaddrinfo.html
> 

Done.

-- 
KO Myung-Hun

Korean OS/2 User Community : https://www.os2.kr/
From e9de288c29df326e552f70de269192494bc2d57a Mon Sep 17 00:00:00 2001
From: KO Myung-Hun <komh78@gmail.com>
Date: Mon, 10 Feb 2025 20:39:05 +0900
Subject: [PATCH v2] getaddrinfo: Supports AI_NUMERICHOST and AI_NUMERICSERV
 flags

* lib/getaddrinfo.c (getaddrinfo): Add AI_NUMERICHOST and AI_NUMERICSERV
as supported flags.
* lib/netdb.in.h: Define AI_NUMERICHOST if not defined yet.
* modules/getaddrinfo (Depends-on): Add inet_pton module.
* tests/test-getaddrinfo.c: Add tests for AI_NUMERICHOST and
AI_NUMERICSERV flags.
---
 lib/getaddrinfo.c        | 26 +++++++++++++++++++++++++-
 lib/netdb.in.h           |  2 +-
 modules/getaddrinfo      |  1 +
 tests/test-getaddrinfo.c | 34 ++++++++++++++++++++++++++--------
 4 files changed, 53 insertions(+), 10 deletions(-)

diff --git a/lib/getaddrinfo.c b/lib/getaddrinfo.c
index cd045c5121..03a93f311d 100644
--- a/lib/getaddrinfo.c
+++ b/lib/getaddrinfo.c
@@ -200,12 +200,14 @@ getaddrinfo (const char *restrict nodename,
     struct addrinfo addrinfo;
     struct sockaddr_in6 sockaddr_in6;
   };
+  struct in6_addr addr6;
 # endif
 # if HAVE_IPV4
   struct v4_pair {
     struct addrinfo addrinfo;
     struct sockaddr_in sockaddr_in;
   };
+  struct in_addr addr4;
 # endif
 
 # ifdef WINDOWS_NATIVE
@@ -213,7 +215,8 @@ getaddrinfo (const char *restrict nodename,
     return getaddrinfo_ptr (nodename, servname, hints, res);
 # endif
 
-  if (hints && (hints->ai_flags & ~(AI_CANONNAME|AI_PASSIVE)))
+  if (hints && (hints->ai_flags &
+                ~(AI_CANONNAME|AI_PASSIVE|AI_NUMERICHOST|AI_NUMERICSERV)))
     /* FIXME: Support more flags. */
     return EAI_BADFLAGS;
 
@@ -237,6 +240,26 @@ getaddrinfo (const char *restrict nodename,
 # endif
     }
 
+  if (hints && (hints->ai_flags & AI_NUMERICHOST))
+    {
+      int valid = 0;
+
+# ifdef HAVE_IPV6
+      valid |= !valid &&
+               (hints->ai_family == AF_INET6 ||
+                hints->ai_family == AF_UNSPEC) &&
+               inet_pton (AF_INET6, nodename, &addr6) == 1;
+# endif
+# ifdef HAVE_IPV4
+      valid |= !valid &&
+               (hints->ai_family == AF_INET ||
+                hints->ai_family == AF_UNSPEC) &&
+               inet_pton (AF_INET, nodename, &addr4) == 1;
+# endif
+      if (!valid)
+        return EAI_NONAME;
+    }
+
   if (servname)
     {
       struct servent *se = NULL;
@@ -261,6 +284,7 @@ getaddrinfo (const char *restrict nodename,
         port = se->s_port;
     }
 
+  /* FIXME: Assume gethostbyname can accept a numeric address string. */
   /* FIXME: Use gethostbyname_r if available. */
   he = gethostbyname (nodename);
   if (!he || he->h_addr_list[0] == NULL)
diff --git a/lib/netdb.in.h b/lib/netdb.in.h
index e8ba8f0978..9cad2d937a 100644
--- a/lib/netdb.in.h
+++ b/lib/netdb.in.h
@@ -103,7 +103,7 @@ struct addrinfo
 #  define AI_NUMERICSERV        0x0400  /* Don't use name resolution.  */
 # endif
 
-# if 0
+# ifndef AI_NUMERICHOST
 #  define AI_NUMERICHOST        0x0004  /* Don't use name resolution.  */
 # endif
 
diff --git a/modules/getaddrinfo b/modules/getaddrinfo
index b31d395635..265886e6c0 100644
--- a/modules/getaddrinfo
+++ b/modules/getaddrinfo
@@ -13,6 +13,7 @@ extensions
 gettext-h       [test $HAVE_GETADDRINFO = 0 || test $REPLACE_GETADDRINFO = 1 || test $HAVE_DECL_GAI_STRERROR = 0 || test $REPLACE_GAI_STRERROR = 1]
 gnulib-i18n     [test $HAVE_GETADDRINFO = 0 || test $REPLACE_GETADDRINFO = 1 || test $HAVE_DECL_GAI_STRERROR = 0 || test $REPLACE_GAI_STRERROR = 1]
 inet_ntop       [test $HAVE_GETADDRINFO = 0 || test $REPLACE_GETADDRINFO = 1]
+inet_pton       [test $HAVE_GETADDRINFO = 0 || test $REPLACE_GETADDRINFO = 1]
 snprintf        [test $HAVE_GETADDRINFO = 0 || test $REPLACE_GETADDRINFO = 1]
 bool            [test $HAVE_GETADDRINFO = 0 || test $REPLACE_GETADDRINFO = 1]
 strdup          [test $HAVE_GETADDRINFO = 0 || test $REPLACE_GETADDRINFO = 1]
diff --git a/tests/test-getaddrinfo.c b/tests/test-getaddrinfo.c
index 968e0052dc..b11a2c6140 100644
--- a/tests/test-getaddrinfo.c
+++ b/tests/test-getaddrinfo.c
@@ -60,7 +60,7 @@ SIGNATURE_CHECK (getaddrinfo, int, (char const *, char const *,
 #endif
 
 static int
-simple (char const *host, char const *service)
+simple (char const *host, char const *service, int flags)
 {
   char buf[BUFSIZ];
   static int skip = 0;
@@ -78,11 +78,11 @@ simple (char const *host, char const *service)
   /* This initializes "hints" but does not use it.  Is there a reason
      for this?  If so, please fix this comment.  */
   memset (&hints, 0, sizeof (hints));
-  hints.ai_flags = AI_CANONNAME;
+  hints.ai_flags = AI_CANONNAME | flags;
   hints.ai_family = AF_UNSPEC;
   hints.ai_socktype = SOCK_STREAM;
 
-  res = getaddrinfo (host, service, NULL, &ai0);
+  res = getaddrinfo (host, service, &hints, &ai0);
   err = errno;
 
   dbgprintf ("res %d: %s\n", res, gai_strerror (res));
@@ -101,7 +101,7 @@ simple (char const *host, char const *service)
       /* IRIX reports EAI_NONAME for "https".  Don't fail the test
          merely because of this.  */
       if (res == EAI_NONAME)
-        return 0;
+        return (flags & (AI_NUMERICHOST | AI_NUMERICSERV)) ? 2 : 0;
       /* Solaris reports EAI_SERVICE for "http" and "https".  Don't
          fail the test merely because of this.  */
       if (res == EAI_SERVICE)
@@ -166,13 +166,31 @@ simple (char const *host, char const *service)
 #define SERV3 "http"
 #define HOST4 "google.org"
 #define SERV4 "ldap"
+#ifdef HAVE_IPV6
+#define NUMERICHOSTV6 "2001:db8:3333:4444:CCCC:DDDD:EEEE:FFFF"
+#endif
+#ifdef HAVE_IPV4
+#define NUMERICHOSTV4 "1.2.3.4"
+#endif
+#define NUMERICSERV "54321"
 
 int main (void)
 {
   (void) gl_sockets_startup (SOCKETS_1_1);
 
-  return simple (HOST1, SERV1)
-    + simple (HOST2, SERV2)
-    + simple (HOST3, SERV3)
-    + simple (HOST4, SERV4);
+  return simple (HOST1, SERV1, 0)
+    + simple (HOST2, SERV2, 0)
+    + simple (HOST3, SERV3, 0)
+    + simple (HOST4, SERV4, 0)
+#ifdef HAVE_IPV6
+    + simple (NUMERICHOSTV6, NUMERICSERV, AI_NUMERICHOST | AI_NUMERICSERV)
+    + !(simple (HOST1, NULL, AI_NUMERICHOST) == 2)
+    + !(simple (NULL, SERV1, AI_NUMERICSERV) == 2)
+#endif
+#ifdef HAVE_IPV4
+    + simple (NUMERICHOSTV4, NUMERICSERV, AI_NUMERICHOST | AI_NUMERICSERV)
+    + !(simple (HOST1, NULL, AI_NUMERICHOST) == 2)
+    + !(simple (NULL, SERV1, AI_NUMERICSERV) == 2)
+#endif
+    ;
 }
-- 
2.42.0

Reply via email to