From 2907036db71b583f6a7c627e1e1753e85c779312 Mon Sep 17 00:00:00 2001
From: Thomas Quinot <quinot@adacore.com>
Date: Mon, 20 Apr 2009 10:45:28 +0000
Subject: [PATCH] socket.c, [...] (__gnat_inet_pton): Needs to be enabled for
 HP-UX as well...

2009-04-20  Thomas Quinot  <quinot@adacore.com>

	* socket.c, g-socthi-vms.adb, g-socthi-vms.ads, g-socthi-vxworks.ads,
	s-oscons-tmplt.c, gsocket.h, g-socthi-mingw.ads, g-socthi.ads,
	g-sothco.ads (__gnat_inet_pton): Needs to be enabled for HP-UX as well,
	since HP-UX supports neither inet_aton nor inet_pton (altough the
	latter is part of the Single UNIX Specification!).
	So reorganize code, and share C implementation based on inet_addr(3)
	with VMS (instead of having a VMS specific Ada implementation in
	g-socthi-vms.adb).

From-SVN: r146396
---
 gcc/ada/ChangeLog            | 11 ++++++++
 gcc/ada/g-socthi-mingw.ads   |  6 -----
 gcc/ada/g-socthi-vms.adb     | 52 ------------------------------------
 gcc/ada/g-socthi-vms.ads     |  5 ----
 gcc/ada/g-socthi-vxworks.ads |  6 -----
 gcc/ada/g-socthi.ads         |  6 -----
 gcc/ada/g-sothco.ads         |  6 +++++
 gcc/ada/gsocket.h            |  4 +++
 gcc/ada/s-oscons-tmplt.c     |  8 ++++++
 gcc/ada/socket.c             | 35 +++++++++++++++++++++---
 10 files changed, 60 insertions(+), 79 deletions(-)

diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index dbd869b3e700..fdadb95a21dc 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,14 @@
+2009-04-20  Thomas Quinot  <quinot@adacore.com>
+
+	* socket.c, g-socthi-vms.adb, g-socthi-vms.ads, g-socthi-vxworks.ads,
+	s-oscons-tmplt.c, gsocket.h, g-socthi-mingw.ads, g-socthi.ads,
+	g-sothco.ads (__gnat_inet_pton): Needs to be enabled for HP-UX as well,
+	since HP-UX supports neither inet_aton nor inet_pton (altough the
+	latter is part of the Single UNIX Specification!).
+	So reorganize code, and share C implementation based on inet_addr(3)
+	with VMS (instead of having a VMS specific Ada implementation in
+	g-socthi-vms.adb).
+
 2009-04-20  Gary Dismukes  <dismukes@adacore.com>
 
 	* osint-c.ads, osint-c.adb (Get_Object_Output_File_Name): New function
diff --git a/gcc/ada/g-socthi-mingw.ads b/gcc/ada/g-socthi-mingw.ads
index 49dd11c06297..e93b3f7be49d 100644
--- a/gcc/ada/g-socthi-mingw.ads
+++ b/gcc/ada/g-socthi-mingw.ads
@@ -115,11 +115,6 @@ package GNAT.Sockets.Thin is
       Optval  : System.Address;
       Optlen  : not null access C.int) return C.int;
 
-   function Inet_Pton
-     (Af  : C.int;
-      Cp  : C.Strings.chars_ptr;
-      Inp : System.Address) return C.int;
-
    function C_Ioctl
      (S    : C.int;
       Req  : C.int;
@@ -234,7 +229,6 @@ private
    pragma Import (Stdcall, C_Getpeername, "getpeername");
    pragma Import (Stdcall, C_Getsockname, "getsockname");
    pragma Import (Stdcall, C_Getsockopt, "getsockopt");
-   pragma Import (C, Inet_Pton, "__gnat_inet_pton");
    pragma Import (Stdcall, C_Ioctl, "ioctlsocket");
    pragma Import (Stdcall, C_Listen, "listen");
    pragma Import (Stdcall, C_Recv, "recv");
diff --git a/gcc/ada/g-socthi-vms.adb b/gcc/ada/g-socthi-vms.adb
index 9ca32f3c4f5e..ab14d8e49176 100644
--- a/gcc/ada/g-socthi-vms.adb
+++ b/gcc/ada/g-socthi-vms.adb
@@ -353,58 +353,6 @@ package body GNAT.Sockets.Thin is
 
    package body Host_Error_Messages is separate;
 
-   ---------------
-   -- Inet_Pton --
-   ---------------
-
-   --  VMS does not support inet_pton(3), so emulate it here in terms of
-   --  inet_addr(3).
-
-   function Inet_Pton
-     (Af  : C.int;
-      Cp  : C.Strings.chars_ptr;
-      Inp : System.Address) return C.int
-   is
-      use C.Strings;
-      use System;
-
-      Res : aliased C.int;
-      package Conv is new System.Address_To_Access_Conversions (C.int);
-      function C_Inet_Addr (Cp : C.Strings.chars_ptr) return C.int;
-      pragma Import (C, C_Inet_Addr, "DECC$INET_ADDR");
-   begin
-      if Af /= SOSC.AF_INET then
-         Set_Socket_Errno (SOSC.EAFNOSUPPORT);
-         return -1;
-      end if;
-
-      if Cp = Null_Ptr or else Inp = Null_Address then
-         return 0;
-      end if;
-
-      --  Special case for the all-ones broadcast address: this address has the
-      --  same in_addr_t value as Failure, and thus cannot be properly returned
-      --  by inet_addr(3).
-
-      if String'(Value (Cp)) = "255.255.255.255" then
-         Conv.To_Pointer (Inp).all := -1;
-         return 1;
-      end if;
-
-      Res := C_Inet_Addr (Cp);
-
-      --  String is not a valid dotted quad
-
-      if Res = -1 then
-         return 0;
-      end if;
-
-      --  Success
-
-      Conv.To_Pointer (Inp).all := Res;
-      return 1;
-   end Inet_Pton;
-
    ----------------
    -- Initialize --
    ----------------
diff --git a/gcc/ada/g-socthi-vms.ads b/gcc/ada/g-socthi-vms.ads
index 1a6e5af99ae6..6a67e21d8a4b 100644
--- a/gcc/ada/g-socthi-vms.ads
+++ b/gcc/ada/g-socthi-vms.ads
@@ -118,11 +118,6 @@ package GNAT.Sockets.Thin is
       Optval  : System.Address;
       Optlen  : not null access C.int) return C.int;
 
-   function Inet_Pton
-     (Af  : C.int;
-      Cp  : C.Strings.chars_ptr;
-      Inp : System.Address) return C.int;
-
    function C_Ioctl
      (S    : C.int;
       Req  : C.int;
diff --git a/gcc/ada/g-socthi-vxworks.ads b/gcc/ada/g-socthi-vxworks.ads
index 30c2b5057b05..04e1278f2be9 100644
--- a/gcc/ada/g-socthi-vxworks.ads
+++ b/gcc/ada/g-socthi-vxworks.ads
@@ -116,11 +116,6 @@ package GNAT.Sockets.Thin is
       Optval  : System.Address;
       Optlen  : not null access C.int) return C.int;
 
-   function Inet_Pton
-     (Af  : C.int;
-      Cp  : C.Strings.chars_ptr;
-      Inp : System.Address) return C.int;
-
    function C_Ioctl
      (S    : C.int;
       Req  : C.int;
@@ -228,7 +223,6 @@ private
    pragma Import (C, C_Getpeername, "getpeername");
    pragma Import (C, C_Getsockname, "getsockname");
    pragma Import (C, C_Getsockopt, "getsockopt");
-   pragma Import (C, Inet_Pton, "__gnat_inet_pton");
    pragma Import (C, C_Listen, "listen");
    pragma Import (C, C_Readv, "readv");
    pragma Import (C, C_Select, "select");
diff --git a/gcc/ada/g-socthi.ads b/gcc/ada/g-socthi.ads
index 720efcdee95e..303a942d3859 100644
--- a/gcc/ada/g-socthi.ads
+++ b/gcc/ada/g-socthi.ads
@@ -117,11 +117,6 @@ package GNAT.Sockets.Thin is
       Optval  : System.Address;
       Optlen  : not null access C.int) return C.int;
 
-   function Inet_Pton
-     (Af  : C.int;
-      Cp  : C.Strings.chars_ptr;
-      Inp : System.Address) return C.int;
-
    function C_Ioctl
      (S    : C.int;
       Req  : C.int;
@@ -253,7 +248,6 @@ private
    pragma Import (C, C_Getpeername, "getpeername");
    pragma Import (C, C_Getsockname, "getsockname");
    pragma Import (C, C_Getsockopt, "getsockopt");
-   pragma Import (C, Inet_Pton, "inet_pton");
    pragma Import (C, C_Listen, "listen");
    pragma Import (C, C_Readv, "readv");
    pragma Import (C, C_Select, "select");
diff --git a/gcc/ada/g-sothco.ads b/gcc/ada/g-sothco.ads
index 5c886b569b71..448677174a86 100644
--- a/gcc/ada/g-sothco.ads
+++ b/gcc/ada/g-sothco.ads
@@ -301,6 +301,11 @@ package GNAT.Sockets.Thin_Common is
    --  Indices into an Fd_Pair value providing access to each of the connected
    --  file descriptors.
 
+   function Inet_Pton
+     (Af  : C.int;
+      Cp  : C.Strings.chars_ptr;
+      Inp : System.Address) return C.int;
+
 private
    pragma Import (C, Get_Socket_From_Set, "__gnat_get_socket_from_set");
    pragma Import (C, Is_Socket_In_Set, "__gnat_is_socket_in_set");
@@ -308,4 +313,5 @@ private
    pragma Import (C, Insert_Socket_In_Set, "__gnat_insert_socket_in_set");
    pragma Import (C, Remove_Socket_From_Set, "__gnat_remove_socket_from_set");
    pragma Import (C, Reset_Socket_Set, "__gnat_reset_socket_set");
+   pragma Import (C, Inet_Pton, SOSC.Inet_Pton_Linkname);
 end GNAT.Sockets.Thin_Common;
diff --git a/gcc/ada/gsocket.h b/gcc/ada/gsocket.h
index 7e88eea47500..16aa2ba4c552 100644
--- a/gcc/ada/gsocket.h
+++ b/gcc/ada/gsocket.h
@@ -230,4 +230,8 @@
 # define Has_Sockaddr_Len 0
 #endif
 
+#if !(defined (__vxworks) || defined (_WIN32) || defined (__hpux__) || defined (VMS))
+# define HAVE_INET_PTON
+#endif
+
 #endif /* defined(__nucleus__) */
diff --git a/gcc/ada/s-oscons-tmplt.c b/gcc/ada/s-oscons-tmplt.c
index 2bcb80a6f0cd..c3511b9b52f1 100644
--- a/gcc/ada/s-oscons-tmplt.c
+++ b/gcc/ada/s-oscons-tmplt.c
@@ -1197,8 +1197,16 @@ CND(Has_Sockaddr_Len,  "Sockaddr has sa_len field")
 TXT("   Thread_Blocking_IO  : constant Boolean := True;")
 /*
    --  Set False for contexts where socket i/o are process blocking
+
 */
 
+#ifdef HAVE_INET_PTON
+# define Inet_Pton_Linkname "inet_pton"
+#else
+# define Inet_Pton_Linkname "__gnat_inet_pton"
+#endif
+TXT("   Inet_Pton_Linkname  : constant String := \"" Inet_Pton_Linkname "\";")
+
 #endif /* HAVE_SOCKETS */
 
 /**
diff --git a/gcc/ada/socket.c b/gcc/ada/socket.c
index 4633ebfd774b..4ac17e2fbbf1 100644
--- a/gcc/ada/socket.c
+++ b/gcc/ada/socket.c
@@ -400,7 +400,13 @@ __gnat_get_h_errno (void) {
 #endif
 }
 
-#if defined (__vxworks) || defined (_WIN32)
+#ifndef HAVE_INET_PTON
+
+#ifdef VMS
+# define in_addr_t int
+# define inet_addr decc$inet_addr
+#endif
+
 int
 __gnat_inet_pton (int af, const char *src, void *dst) {
   switch (af) {
@@ -414,9 +420,10 @@ __gnat_inet_pton (int af, const char *src, void *dst) {
       return -1;
   }
 
-#ifdef __vxworks
+#if defined (__vxworks)
   return (inet_aton (src, dst) == OK);
-#else
+
+#elif defined (_WIN32)
   struct sockaddr_storage ss;
   int sslen = sizeof ss;
   int rc;
@@ -436,10 +443,30 @@ __gnat_inet_pton (int af, const char *src, void *dst) {
     }
   }
   return (rc == 0);
+
+#elif defined (__hpux__) || defined (VMS)
+  in_addr_t addr;
+  int rc = -1;
+
+  if (src == NULL || dst == NULL) {
+    errno = EINVAL;
+
+  } else if (!strcmp (src, "255.255.255.255")) {
+    addr = 0xffffffff;
+    rc = 1;
+
+  } else {
+    addr = inet_addr (src);
+    rc = (addr != 0xffffffff);
+  }
+  if (rc == 1) {
+    *(in_addr_t *)dst = addr;
+  }
+  return rc;
 #endif
 }
 #endif
 
 #else
-#warning Sockets are not supported on this platform
+# warning Sockets are not supported on this platform
 #endif /* defined(HAVE_SOCKETS) */
-- 
GitLab