------------------------------------------------------------------------------
--                                                                          --
--                         GNAT COMPILER COMPONENTS                         --
--                                                                          --
--                         G N A T . S O C K E T S                          --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--                     Copyright (C) 2001-2021, AdaCore                     --
--                                                                          --
-- GNAT is free software;  you can  redistribute it  and/or modify it under --
-- terms of the  GNU General Public License as published  by the Free Soft- --
-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
--                                                                          --
-- As a special exception under Section 7 of GPL version 3, you are granted --
-- additional permissions described in the GCC Runtime Library Exception,   --
-- version 3.1, as published by the Free Software Foundation.               --
--                                                                          --
-- You should have received a copy of the GNU General Public License and    --
-- a copy of the GCC Runtime Library Exception along with this program;     --
-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
-- <http://www.gnu.org/licenses/>.                                          --
--                                                                          --
-- GNAT was originally developed  by the GNAT team at  New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc.      --
--                                                                          --
------------------------------------------------------------------------------

with Ada.Containers.Generic_Array_Sort;
with Ada.Exceptions;           use Ada.Exceptions;
with Ada.Finalization;
with Ada.Streams;              use Ada.Streams;
with Ada.Unchecked_Conversion;

with GNAT.Sockets.Thin;        use GNAT.Sockets.Thin;
with GNAT.Sockets.Thin_Common; use GNAT.Sockets.Thin_Common;

with GNAT.Sockets.Linker_Options;
pragma Warnings (Off, GNAT.Sockets.Linker_Options);
--  Need to include pragma Linker_Options which is platform dependent

with GNAT.Sockets.Poll;

with System;               use System;
with System.Communication; use System.Communication;
with System.CRTL;          use System.CRTL;
with System.Task_Lock;

package body GNAT.Sockets is

   package C renames Interfaces.C;

   type IPV6_Mreq is record
      ipv6mr_multiaddr : In6_Addr;
      ipv6mr_interface : C.unsigned;
   end record with Convention => C;
   --  Record to Add/Drop_Membership for multicast in IPv6

   ENOERROR : constant := 0;

   Netdb_Buffer_Size : constant := SOSC.Need_Netdb_Buffer * 1024;
   Need_Netdb_Lock   : constant Boolean := SOSC.Need_Netdb_Lock /= 0;
   --  The network database functions gethostbyname, gethostbyaddr,
   --  getservbyname and getservbyport can either be guaranteed task safe by
   --  the operating system, or else return data through a user-provided buffer
   --  to ensure concurrent uses do not interfere.

   --  Correspondence tables

   Levels : constant array (Level_Type) of C.int :=
              (Socket_Level               => SOSC.SOL_SOCKET,
               IP_Protocol_For_IP_Level   => SOSC.IPPROTO_IP,
               IP_Protocol_For_IPv6_Level => SOSC.IPPROTO_IPV6,
               IP_Protocol_For_UDP_Level  => SOSC.IPPROTO_UDP,
               IP_Protocol_For_TCP_Level  => SOSC.IPPROTO_TCP,
               IP_Protocol_For_ICMP_Level => SOSC.IPPROTO_ICMP,
               IP_Protocol_For_IGMP_Level => SOSC.IPPROTO_IGMP,
               IP_Protocol_For_RAW_Level  => SOSC.IPPROTO_RAW);

   Modes : constant array (Mode_Type) of C.int :=
             (Socket_Stream   => SOSC.SOCK_STREAM,
              Socket_Datagram => SOSC.SOCK_DGRAM,
              Socket_Raw      => SOSC.SOCK_RAW);

   Shutmodes : constant array (Shutmode_Type) of C.int :=
                 (Shut_Read       => SOSC.SHUT_RD,
                  Shut_Write      => SOSC.SHUT_WR,
                  Shut_Read_Write => SOSC.SHUT_RDWR);

   Requests : constant array (Request_Name) of SOSC.IOCTL_Req_T :=
                (Non_Blocking_IO => SOSC.FIONBIO,
                 N_Bytes_To_Read => SOSC.FIONREAD);

   Options : constant array (Specific_Option_Name) of C.int :=
               (Keep_Alive          => SOSC.SO_KEEPALIVE,
                Keep_Alive_Count    => SOSC.TCP_KEEPCNT,
                Keep_Alive_Idle     => SOSC.TCP_KEEPIDLE,
                Keep_Alive_Interval => SOSC.TCP_KEEPINTVL,
                Reuse_Address       => SOSC.SO_REUSEADDR,
                Broadcast           => SOSC.SO_BROADCAST,
                Send_Buffer         => SOSC.SO_SNDBUF,
                Receive_Buffer      => SOSC.SO_RCVBUF,
                Linger              => SOSC.SO_LINGER,
                Error               => SOSC.SO_ERROR,
                No_Delay            => SOSC.TCP_NODELAY,
                Add_Membership_V4   => SOSC.IP_ADD_MEMBERSHIP,
                Drop_Membership_V4  => SOSC.IP_DROP_MEMBERSHIP,
                Multicast_If_V4     => SOSC.IP_MULTICAST_IF,
                Multicast_Loop_V4   => SOSC.IP_MULTICAST_LOOP,
                Receive_Packet_Info => SOSC.IP_PKTINFO,
                Multicast_TTL       => SOSC.IP_MULTICAST_TTL,
                Add_Membership_V6   => SOSC.IPV6_ADD_MEMBERSHIP,
                Drop_Membership_V6  => SOSC.IPV6_DROP_MEMBERSHIP,
                Multicast_If_V6     => SOSC.IPV6_MULTICAST_IF,
                Multicast_Loop_V6   => SOSC.IPV6_MULTICAST_LOOP,
                Multicast_Hops      => SOSC.IPV6_MULTICAST_HOPS,
                IPv6_Only           => SOSC.IPV6_V6ONLY,
                Send_Timeout        => SOSC.SO_SNDTIMEO,
                Receive_Timeout     => SOSC.SO_RCVTIMEO,
                Busy_Polling        => SOSC.SO_BUSY_POLL);
   --  ??? Note: for OpenSolaris, Receive_Packet_Info should be IP_RECVPKTINFO,
   --  but for Linux compatibility this constant is the same as IP_PKTINFO.

   Flags : constant array (0 .. 3) of C.int :=
             (0 => SOSC.MSG_OOB,     --  Process_Out_Of_Band_Data
              1 => SOSC.MSG_PEEK,    --  Peek_At_Incoming_Data
              2 => SOSC.MSG_WAITALL, --  Wait_For_A_Full_Reception
              3 => SOSC.MSG_EOR);    --  Send_End_Of_Record

   Socket_Error_Id : constant Exception_Id := Socket_Error'Identity;
   Host_Error_Id   : constant Exception_Id := Host_Error'Identity;

   type In_Addr_Union (Family : Family_Inet_4_6) is record
      case Family is
         when Family_Inet =>
            In4 : In_Addr;
         when Family_Inet6 =>
            In6 : In6_Addr;
      end case;
   end record with Unchecked_Union;

   -----------------------
   -- Local subprograms --
   -----------------------

   function Resolve_Error
     (Error_Value : Integer;
      From_Errno  : Boolean := True) return Error_Type;
   --  Associate an enumeration value (error_type) to an error value (errno).
   --  From_Errno prevents from mixing h_errno with errno.

   function To_Name   (N  : String) return Name_Type;
   function To_String (HN : Name_Type) return String;
   --  Conversion functions

   function To_Int (F : Request_Flag_Type) return C.int;
   --  Return the int value corresponding to the specified flags combination

   function Set_Forced_Flags (F : C.int) return C.int;
   --  Return F with the bits from SOSC.MSG_Forced_Flags forced set

   procedure Netdb_Lock;
   pragma Inline (Netdb_Lock);
   procedure Netdb_Unlock;
   pragma Inline (Netdb_Unlock);
   --  Lock/unlock operation used to protect netdb access for platforms that
   --  require such protection.

   function To_Host_Entry (E : Hostent_Access) return Host_Entry_Type;
   --  Conversion function

   function To_Service_Entry (E : Servent_Access) return Service_Entry_Type;
   --  Conversion function

   function Value (S : System.Address) return String;
   --  Same as Interfaces.C.Strings.Value but taking a System.Address

   function To_Timeval (Val : Timeval_Duration) return Timeval;
   --  Separate Val in seconds and microseconds

   function To_Duration (Val : Timeval) return Timeval_Duration;
   --  Reconstruct a Duration value from a Timeval record (seconds and
   --  microseconds).

   function Dedot (Value : String) return String
   is (if Value /= "" and then Value (Value'Last) = '.'
       then Value (Value'First .. Value'Last - 1)
       else Value);
   --  Removes dot at the end of error message

   procedure Raise_Host_Error (H_Error : Integer; Name : String);
   --  Raise Host_Error exception with message describing error code (note
   --  hstrerror seems to be obsolete) from h_errno. Name is the name
   --  or address that was being looked up.

   procedure Raise_GAI_Error (RC : C.int; Name : String);
   --  Raise Host_Error with exception message in case of errors in
   --  getaddrinfo and getnameinfo.

   function Is_Windows return Boolean with Inline;
   --  Returns True on Windows platform

   procedure Narrow (Item : in out Socket_Set_Type);
   --  Update Last as it may be greater than the real last socket

   procedure Check_For_Fd_Set (Fd : Socket_Type);
   pragma Inline (Check_For_Fd_Set);
   --  Raise Constraint_Error if Fd is less than 0 or greater than or equal to
   --  FD_SETSIZE, on platforms where fd_set is a bitmap.

   function Connect_Socket
     (Socket : Socket_Type;
      Server : Sock_Addr_Type) return C.int;
   pragma Inline (Connect_Socket);
   --  Underlying implementation for the Connect_Socket procedures

   --  Types needed for Datagram_Socket_Stream_Type

   type Datagram_Socket_Stream_Type is new Root_Stream_Type with record
      Socket : Socket_Type;
      To     : Sock_Addr_Type;
      From   : Sock_Addr_Type;
   end record;

   type Datagram_Socket_Stream_Access is
     access all Datagram_Socket_Stream_Type;

   procedure Read
     (Stream : in out Datagram_Socket_Stream_Type;
      Item   : out Ada.Streams.Stream_Element_Array;
      Last   : out Ada.Streams.Stream_Element_Offset);

   procedure Write
     (Stream : in out Datagram_Socket_Stream_Type;
      Item   : Ada.Streams.Stream_Element_Array);

   --  Types needed for Stream_Socket_Stream_Type

   type Stream_Socket_Stream_Type is new Root_Stream_Type with record
      Socket : Socket_Type;
   end record;

   type Stream_Socket_Stream_Access is
     access all Stream_Socket_Stream_Type;

   procedure Read
     (Stream : in out Stream_Socket_Stream_Type;
      Item   : out Ada.Streams.Stream_Element_Array;
      Last   : out Ada.Streams.Stream_Element_Offset);

   procedure Write
     (Stream : in out Stream_Socket_Stream_Type;
      Item   : Ada.Streams.Stream_Element_Array);

   procedure Wait_On_Socket
     (Socket   : Socket_Type;
      Event    : Poll.Wait_Event_Set;
      Timeout  : Selector_Duration;
      Selector : access Selector_Type := null;
      Status   : out Selector_Status);
   --  Common code for variants of socket operations supporting a timeout:
   --  block in Poll.Wait on Socket for at most the indicated timeout.
   --  Event parameter defines what the Poll.Wait is waiting for.

   type Sockets_Library_Controller is new Ada.Finalization.Limited_Controlled
     with null record;
   --  This type is used to generate automatic calls to Initialize and Finalize
   --  during the elaboration and finalization of this package. A single object
   --  of this type must exist at library level.

   function Err_Code_Image (E : Integer) return String;
   --  Return the value of E surrounded with brackets

   procedure Initialize (X : in out Sockets_Library_Controller);
   procedure Finalize   (X : in out Sockets_Library_Controller);

   procedure Normalize_Empty_Socket_Set (S : in out Socket_Set_Type);
   --  If S is the empty set (detected by Last = No_Socket), make sure its
   --  fd_set component is actually cleared. Note that the case where it is
   --  not can occur for an uninitialized Socket_Set_Type object.

   function Is_Open (S : Selector_Type) return Boolean;
   --  Return True for an "open" Selector_Type object, i.e. one for which
   --  Create_Selector has been called and Close_Selector has not been called,
   --  or the null selector.

   function Create_Address
     (Family : Family_Inet_4_6; Bytes : Inet_Addr_Bytes) return Inet_Addr_Type
     with Inline;
   --  Creates address from family and Inet_Addr_Bytes array

   function Get_Bytes (Addr : Inet_Addr_Type) return Inet_Addr_Bytes
     with Inline;
   --  Extract bytes from address

   ---------
   -- "+" --
   ---------

   function "+" (L, R : Request_Flag_Type) return Request_Flag_Type is
   begin
      return L or R;
   end "+";

   --------------------
   -- Abort_Selector --
   --------------------

   procedure Abort_Selector (Selector : Selector_Type) is
      Res : C.int;

   begin
      if not Is_Open (Selector) then
         raise Program_Error with "closed selector";

      elsif Selector.Is_Null then
         raise Program_Error with "null selector";

      end if;

      --  Send one byte to unblock select system call

      Res := Signalling_Fds.Write (C.int (Selector.W_Sig_Socket));

      if Res = Failure then
         Raise_Socket_Error (Socket_Errno);
      end if;
   end Abort_Selector;

   -------------------
   -- Accept_Socket --
   -------------------

   procedure Accept_Socket
     (Server  : Socket_Type;
      Socket  : out Socket_Type;
      Address : out Sock_Addr_Type)
   is
      Res : C.int;
      Sin : aliased Sockaddr;
      Len : aliased C.int := Sin'Size / 8;

   begin
      Res := C_Accept (C.int (Server), Sin'Address, Len'Access);

      if Res = Failure then
         Raise_Socket_Error (Socket_Errno);
      end if;

      Socket := Socket_Type (Res);
      Address := Get_Address (Sin, Len);
   end Accept_Socket;

   -------------------
   -- Accept_Socket --
   -------------------

   procedure Accept_Socket
     (Server   : Socket_Type;
      Socket   : out Socket_Type;
      Address  : out Sock_Addr_Type;
      Timeout  : Selector_Duration;
      Selector : access Selector_Type := null;
      Status   : out Selector_Status)
   is
   begin
      if Selector /= null and then not Is_Open (Selector.all) then
         raise Program_Error with "closed selector";
      end if;

      --  Wait for socket to become available for reading

      Wait_On_Socket
        (Socket   => Server,
         Event    => Poll.Input_Event,
         Timeout  => Timeout,
         Selector => Selector,
         Status   => Status);

      --  Accept connection if available

      if Status = Completed then
         Accept_Socket (Server, Socket, Address);
      else
         Socket := No_Socket;
      end if;
   end Accept_Socket;

   ---------------
   -- Addresses --
   ---------------

   function Addresses
     (E : Host_Entry_Type;
      N : Positive := 1) return Inet_Addr_Type
   is
   begin
      return E.Addresses (N);
   end Addresses;

   ----------------------
   -- Addresses_Length --
   ----------------------

   function Addresses_Length (E : Host_Entry_Type) return Natural is
   begin
      return E.Addresses_Length;
   end Addresses_Length;

   -------------
   -- Aliases --
   -------------

   function Aliases
     (E : Host_Entry_Type;
      N : Positive := 1) return String
   is
   begin
      return To_String (E.Aliases (N));
   end Aliases;

   -------------
   -- Aliases --
   -------------

   function Aliases
     (S : Service_Entry_Type;
      N : Positive := 1) return String
   is
   begin
      return To_String (S.Aliases (N));
   end Aliases;

   --------------------
   -- Aliases_Length --
   --------------------

   function Aliases_Length (E : Host_Entry_Type) return Natural is
   begin
      return E.Aliases_Length;
   end Aliases_Length;

   --------------------
   -- Aliases_Length --
   --------------------

   function Aliases_Length (S : Service_Entry_Type) return Natural is
   begin
      return S.Aliases_Length;
   end Aliases_Length;

   -----------------
   -- Bind_Socket --
   -----------------

   procedure Bind_Socket
     (Socket  : Socket_Type;
      Address : Sock_Addr_Type)
   is
      Res : C.int;
      Sin : aliased Sockaddr;
      Len : C.int;

   begin
      Set_Address (Sin'Unchecked_Access, Address, Len);

      Res := C_Bind (C.int (Socket), Sin'Address, Len);

      if Res = Failure then
         Raise_Socket_Error (Socket_Errno);
      end if;
   end Bind_Socket;

   ----------------------
   -- Check_For_Fd_Set --
   ----------------------

   procedure Check_For_Fd_Set (Fd : Socket_Type) is
   begin
      --  On Windows, fd_set is a FD_SETSIZE array of socket ids:
      --  no check required. Warnings suppressed because condition
      --  is known at compile time.

      if Is_Windows then

         return;

      --  On other platforms, fd_set is an FD_SETSIZE bitmap: check
      --  that Fd is within range (otherwise behavior is undefined).

      elsif Fd < 0 or else Fd >= SOSC.FD_SETSIZE then
         raise Constraint_Error
           with "invalid value for socket set: " & Image (Fd);
      end if;
   end Check_For_Fd_Set;

   --------------------
   -- Check_Selector --
   --------------------

   procedure Check_Selector
     (Selector     : Selector_Type;
      R_Socket_Set : in out Socket_Set_Type;
      W_Socket_Set : in out Socket_Set_Type;
      Status       : out Selector_Status;
      Timeout      : Selector_Duration := Forever)
   is
      E_Socket_Set : Socket_Set_Type;
   begin
      Check_Selector
        (Selector, R_Socket_Set, W_Socket_Set, E_Socket_Set, Status, Timeout);
   end Check_Selector;

   procedure Check_Selector
     (Selector     : Selector_Type;
      R_Socket_Set : in out Socket_Set_Type;
      W_Socket_Set : in out Socket_Set_Type;
      E_Socket_Set : in out Socket_Set_Type;
      Status       : out Selector_Status;
      Timeout      : Selector_Duration := Forever)
   is
      Res  : C.int;
      Last : C.int;
      RSig : Socket_Type := No_Socket;
      TVal : aliased Timeval;
      TPtr : Timeval_Access;

   begin
      if not Is_Open (Selector) then
         raise Program_Error with "closed selector";
      end if;

      Status := Completed;

      --  No timeout or Forever is indicated by a null timeval pointer

      if Timeout = Forever then
         TPtr := null;
      else
         TVal := To_Timeval (Timeout);
         TPtr := TVal'Unchecked_Access;
      end if;

      --  Add read signalling socket, if present

      if not Selector.Is_Null then
         RSig := Selector.R_Sig_Socket;
         Set (R_Socket_Set, RSig);
      end if;

      Last := C.int'Max (C.int'Max (C.int (R_Socket_Set.Last),
                                    C.int (W_Socket_Set.Last)),
                                    C.int (E_Socket_Set.Last));

      --  Zero out fd_set for empty Socket_Set_Type objects

      Normalize_Empty_Socket_Set (R_Socket_Set);
      Normalize_Empty_Socket_Set (W_Socket_Set);
      Normalize_Empty_Socket_Set (E_Socket_Set);

      Res :=
        C_Select
         (Last + 1,
          R_Socket_Set.Set'Access,
          W_Socket_Set.Set'Access,
          E_Socket_Set.Set'Access,
          TPtr);

      if Res = Failure then
         Raise_Socket_Error (Socket_Errno);
      end if;

      --  If Select was resumed because of read signalling socket, read this
      --  data and remove socket from set.

      if RSig /= No_Socket and then Is_Set (R_Socket_Set, RSig) then
         Clear (R_Socket_Set, RSig);

         Res := Signalling_Fds.Read (C.int (RSig));

         if Res = Failure then
            Raise_Socket_Error (Socket_Errno);
         end if;

         Status := Aborted;

      elsif Res = 0 then
         Status := Expired;
      end if;

      --  Update socket sets in regard to their new contents

      Narrow (R_Socket_Set);
      Narrow (W_Socket_Set);
      Narrow (E_Socket_Set);
   end Check_Selector;

   -----------
   -- Clear --
   -----------

   procedure Clear
     (Item   : in out Socket_Set_Type;
      Socket : Socket_Type)
   is
      Last : aliased C.int := C.int (Item.Last);

   begin
      Check_For_Fd_Set (Socket);

      if Item.Last /= No_Socket then
         Remove_Socket_From_Set (Item.Set'Access, C.int (Socket));
         Last_Socket_In_Set (Item.Set'Access, Last'Unchecked_Access);
         Item.Last := Socket_Type (Last);
      end if;
   end Clear;

   --------------------
   -- Close_Selector --
   --------------------

   procedure Close_Selector (Selector : in out Selector_Type) is
   begin
      --  Nothing to do if selector already in closed state

      if Selector.Is_Null or else not Is_Open (Selector) then
         return;
      end if;

      --  Close the signalling file descriptors used internally for the
      --  implementation of Abort_Selector.

      Signalling_Fds.Close (C.int (Selector.R_Sig_Socket));
      Signalling_Fds.Close (C.int (Selector.W_Sig_Socket));

      --  Reset R_Sig_Socket and W_Sig_Socket to No_Socket to ensure that any
      --  (erroneous) subsequent attempt to use this selector properly fails.

      Selector.R_Sig_Socket := No_Socket;
      Selector.W_Sig_Socket := No_Socket;
   end Close_Selector;

   ------------------
   -- Close_Socket --
   ------------------

   procedure Close_Socket (Socket : Socket_Type) is
      Res : C.int;

   begin
      Res := C_Close (C.int (Socket));

      if Res = Failure then
         Raise_Socket_Error (Socket_Errno);
      end if;
   end Close_Socket;

   --------------------
   -- Connect_Socket --
   --------------------

   function Connect_Socket
     (Socket : Socket_Type;
      Server : Sock_Addr_Type) return C.int
   is
      Sin : aliased Sockaddr;
      Len : C.int;
   begin
      Set_Address (Sin'Unchecked_Access, Server, Len);

      return C_Connect (C.int (Socket), Sin'Address, Len);
   end Connect_Socket;

   procedure Connect_Socket
     (Socket : Socket_Type;
      Server : Sock_Addr_Type)
   is
   begin
      if Connect_Socket (Socket, Server) = Failure then
         Raise_Socket_Error (Socket_Errno);
      end if;
   end Connect_Socket;

   procedure Connect_Socket
     (Socket   : Socket_Type;
      Server   : Sock_Addr_Type;
      Timeout  : Selector_Duration;
      Selector : access Selector_Type := null;
      Status   : out Selector_Status)
   is
      Req : Request_Type;
      --  Used to set Socket to non-blocking I/O

      Conn_Err : aliased Integer;
      --  Error status of the socket after completion of select(2)

      Res           : C.int;
      Conn_Err_Size : aliased C.int := Conn_Err'Size / 8;
      --  For getsockopt(2) call

   begin
      if Selector /= null and then not Is_Open (Selector.all) then
         raise Program_Error with "closed selector";
      end if;

      --  Set the socket to non-blocking I/O

      Req := (Name => Non_Blocking_IO, Enabled => True);
      Control_Socket (Socket, Request => Req);

      --  Start operation (non-blocking), will return Failure with errno set
      --  to EINPROGRESS.

      Res := Connect_Socket (Socket, Server);
      if Res = Failure then
         Conn_Err := Socket_Errno;
         if Conn_Err /= SOSC.EINPROGRESS then
            Raise_Socket_Error (Conn_Err);
         end if;
      end if;

      --  Wait for socket to become available for writing (unless the Timeout
      --  is zero, in which case we consider that it has already expired, and
      --  we do not need to wait at all).

      if Timeout = 0.0 then
         Status := Expired;

      else
         Wait_On_Socket
           (Socket   => Socket,
            Event    => Poll.Output_Event,
            Timeout  => Timeout,
            Selector => Selector,
            Status   => Status);
      end if;

      --  Check error condition (the asynchronous connect may have terminated
      --  with an error, e.g. ECONNREFUSED) if select(2) completed.

      if Status = Completed then
         Res := C_Getsockopt
           (C.int (Socket), SOSC.SOL_SOCKET, SOSC.SO_ERROR,
            Conn_Err'Address, Conn_Err_Size'Access);

         if Res /= 0 then
            Conn_Err := Socket_Errno;
         end if;

      else
         Conn_Err := 0;
      end if;

      --  Reset the socket to blocking I/O

      Req := (Name => Non_Blocking_IO, Enabled => False);
      Control_Socket (Socket, Request => Req);

      --  Report error condition if any

      if Conn_Err /= 0 then
         Raise_Socket_Error (Conn_Err);
      end if;
   end Connect_Socket;

   --------------------
   -- Control_Socket --
   --------------------

   procedure Control_Socket
     (Socket  : Socket_Type;
      Request : in out Request_Type)
   is
      Arg : aliased C.int;
      Res : C.int;

   begin
      case Request.Name is
         when Non_Blocking_IO =>
            Arg := C.int (Boolean'Pos (Request.Enabled));

         when N_Bytes_To_Read =>
            null;
      end case;

      Res := Socket_Ioctl
               (C.int (Socket), Requests (Request.Name), Arg'Unchecked_Access);

      if Res = Failure then
         Raise_Socket_Error (Socket_Errno);
      end if;

      case Request.Name is
         when Non_Blocking_IO =>
            null;

         when N_Bytes_To_Read =>
            Request.Size := Natural (Arg);
      end case;
   end Control_Socket;

   ----------
   -- Copy --
   ----------

   procedure Copy
     (Source : Socket_Set_Type;
      Target : out Socket_Set_Type)
   is
   begin
      Target := Source;
   end Copy;

   ---------------------
   -- Create_Selector --
   ---------------------

   procedure Create_Selector (Selector : out Selector_Type) is
      Two_Fds : aliased Fd_Pair;
      Res     : C.int;

   begin
      if Is_Open (Selector) then
         --  Raise exception to prevent socket descriptor leak

         raise Program_Error with "selector already open";
      end if;

      --  We open two signalling file descriptors. One of them is used to send
      --  data to the other, which is included in a C_Select socket set. The
      --  communication is used to force a call to C_Select to complete, and
      --  the waiting task to resume its execution.

      Res := Signalling_Fds.Create (Two_Fds'Access);
      pragma Annotate (CodePeer, Modified, Two_Fds);

      if Res = Failure then
         Raise_Socket_Error (Socket_Errno);
      end if;

      Selector.R_Sig_Socket := Socket_Type (Two_Fds (Read_End));
      Selector.W_Sig_Socket := Socket_Type (Two_Fds (Write_End));
   end Create_Selector;

   -------------------
   -- Create_Socket --
   -------------------

   procedure Create_Socket
     (Socket : out Socket_Type;
      Family : Family_Type := Family_Inet;
      Mode   : Mode_Type   := Socket_Stream;
      Level  : Level_Type  := IP_Protocol_For_IP_Level)
   is
      Res : C.int;

   begin
      Res := C_Socket (Families (Family), Modes (Mode), Levels (Level));

      if Res = Failure then
         Raise_Socket_Error (Socket_Errno);
      end if;

      Socket := Socket_Type (Res);
   end Create_Socket;

   ------------------------
   -- Create_Socket_Pair --
   ------------------------

   procedure Create_Socket_Pair
     (Left   : out Socket_Type;
      Right  : out Socket_Type;
      Family : Family_Type := Family_Unspec;
      Mode   : Mode_Type   := Socket_Stream;
      Level  : Level_Type  := IP_Protocol_For_IP_Level)
   is
      Res  : C.int;
      Pair : aliased Thin_Common.Fd_Pair;

   begin
      Res := C_Socketpair
        ((if Family = Family_Unspec then Default_Socket_Pair_Family
          else Families (Family)),
         Modes (Mode), Levels (Level), Pair'Access);
      pragma Annotate (CodePeer, Modified, Pair);

      if Res = Failure then
         Raise_Socket_Error (Socket_Errno);
      end if;

      Left  := Socket_Type (Pair (Pair'First));
      Right := Socket_Type (Pair (Pair'Last));
   end Create_Socket_Pair;

   -----------
   -- Empty --
   -----------

   procedure Empty (Item : out Socket_Set_Type) is
   begin
      Reset_Socket_Set (Item.Set'Access);
      Item.Last := No_Socket;
   end Empty;

   --------------------
   -- Err_Code_Image --
   --------------------

   function Err_Code_Image (E : Integer) return String is
      Msg : String := E'Img & "] ";
   begin
      Msg (Msg'First) := '[';
      return Msg;
   end Err_Code_Image;

   --------------
   -- Finalize --
   --------------

   procedure Finalize (X : in out Sockets_Library_Controller) is
      pragma Unreferenced (X);

   begin
      --  Finalization operation for the GNAT.Sockets package

      Thin.Finalize;
   end Finalize;

   --------------
   -- Finalize --
   --------------

   procedure Finalize is
   begin
      --  This is a dummy placeholder for an obsolete API.
      --  The real finalization actions are in Initialize primitive operation
      --  of Sockets_Library_Controller.

      null;
   end Finalize;

   ---------
   -- Get --
   ---------

   procedure Get
     (Item   : in out Socket_Set_Type;
      Socket : out Socket_Type)
   is
      S : aliased C.int;
      L : aliased C.int := C.int (Item.Last);

   begin
      if Item.Last /= No_Socket then
         Get_Socket_From_Set
           (Item.Set'Access, Last => L'Access, Socket => S'Access);
         pragma Annotate (CodePeer, Modified, L);
         pragma Annotate (CodePeer, Modified, S);

         Item.Last := Socket_Type (L);
         Socket    := Socket_Type (S);

      else
         Socket := No_Socket;
      end if;
   end Get;

   -----------------
   -- Get_Address --
   -----------------

   function Get_Address
     (Stream : not null Stream_Access) return Sock_Addr_Type
   is
   begin
      if Stream.all in Datagram_Socket_Stream_Type then
         return Datagram_Socket_Stream_Type (Stream.all).From;
      else
         return Get_Peer_Name (Stream_Socket_Stream_Type (Stream.all).Socket);
      end if;
   end Get_Address;

   ---------------------
   -- Raise_GAI_Error --
   ---------------------

   procedure Raise_GAI_Error (RC : C.int; Name : String) is
   begin
      if RC = SOSC.EAI_SYSTEM then
         declare
            Errcode : constant Integer := Socket_Errno;
         begin
            raise Host_Error with Err_Code_Image (Errcode)
              & Dedot (Socket_Error_Message (Errcode)) & ": " & Name;
         end;
      else
         raise Host_Error with Err_Code_Image (Integer (RC))
           & Dedot (CS.Value (C_GAI_Strerror (RC))) & ": " & Name;
      end if;
   end Raise_GAI_Error;

   ----------------------
   -- Get_Address_Info --
   ----------------------

   function Get_Address_Info
     (Host         : String;
      Service      : String;
      Family       : Family_Type := Family_Unspec;
      Mode         : Mode_Type   := Socket_Stream;
      Level        : Level_Type  := IP_Protocol_For_IP_Level;
      Numeric_Host : Boolean     := False;
      Passive      : Boolean     := False;
      Unknown      : access procedure
        (Family, Mode, Level, Length : Integer) := null)
      return Address_Info_Array
   is
      A : aliased Addrinfo_Access;
      N : aliased C.char_array := C.To_C (Host);
      S : aliased C.char_array := C.To_C (if Service = "" then "0"
                                          else Service);
      Hints : aliased constant Addrinfo :=
        (ai_family   => Families (Family),
         ai_socktype => Modes (Mode),
         ai_protocol => Levels (Level),
         ai_flags    => (if Numeric_Host then SOSC.AI_NUMERICHOST else 0) +
                        (if Passive then SOSC.AI_PASSIVE else 0),
         ai_addrlen  => 0,
         others      => <>);

      R     : C.int;
      Iter  : Addrinfo_Access;
      Found : Boolean;

      function To_Array return Address_Info_Array;
      --  Convert taken from OS addrinfo list A into Address_Info_Array

      --------------
      -- To_Array --
      --------------

      function To_Array return Address_Info_Array is
         Result : Address_Info_Array (1 .. 8);

         procedure Unsupported;
         --  Calls Unknown callback if defiend

         -----------------
         -- Unsupported --
         -----------------

         procedure Unsupported is
         begin
            if Unknown /= null then
               Unknown
                 (Integer (Iter.ai_family),
                  Integer (Iter.ai_socktype),
                  Integer (Iter.ai_protocol),
                  Integer (Iter.ai_addrlen));
            end if;
         end Unsupported;

      --  Start of processing for To_Array

      begin
         for J in Result'Range loop
            Look_For_Supported : loop
               if Iter = null then
                  pragma Warnings
                    (Off, "may be referenced before it has a value");

                  return Result (1 .. J - 1);

                  pragma Warnings
                    (On, "may be referenced before it has a value");
               end if;

               Result (J).Addr :=
                 Get_Address (Iter.ai_addr.all, C.int (Iter.ai_addrlen));

               if Result (J).Addr.Family = Family_Unspec then
                  Unsupported;
               else
                  for M in Modes'Range loop
                     Found := False;
                     if Modes (M) = Iter.ai_socktype then
                        Result (J).Mode := M;
                        Found := True;
                        exit;
                     end if;
                  end loop;

                  if Found then
                     for L in Levels'Range loop
                        if Levels (L) = Iter.ai_protocol then
                           Result (J).Level := L;
                           exit;
                        end if;
                     end loop;

                     exit Look_For_Supported;
                  else
                     Unsupported;
                  end if;
               end if;

               Iter := Iter.ai_next;
            end loop Look_For_Supported;

            Iter := Iter.ai_next;
         end loop;

         return Result & To_Array;
      end To_Array;

   --  Start of processing for Get_Address_Info

   begin
      R := C_Getaddrinfo
        (Node    => (if Host = "" then null else N'Unchecked_Access),
         Service => S'Unchecked_Access,
         Hints   => Hints'Unchecked_Access,
         Res     => A'Access);

      if R /= 0 then
         Raise_GAI_Error
           (R, Host & (if Service = "" then "" else ':' & Service));
      end if;

      Iter := A;

      return Result : constant Address_Info_Array := To_Array do
         C_Freeaddrinfo (A);
      end return;
   end Get_Address_Info;

   ----------
   -- Sort --
   ----------

   procedure Sort
     (Addr_Info : in out Address_Info_Array;
      Compare   : access function (Left, Right : Address_Info) return Boolean)
   is
      function Comp (Left, Right : Address_Info) return Boolean is
         (Compare (Left, Right));
      procedure Sorter is new Ada.Containers.Generic_Array_Sort
        (Positive, Address_Info, Address_Info_Array, Comp);
   begin
      Sorter (Addr_Info);
   end Sort;

   ------------------------
   -- IPv6_TCP_Preferred --
   ------------------------

   function IPv6_TCP_Preferred (Left, Right : Address_Info) return Boolean is
   begin
      pragma Assert (Family_Inet < Family_Inet6);
      --  To be sure that Family_Type enumeration has appropriate elements
      --  order

      if Left.Addr.Family /= Right.Addr.Family then
         return Left.Addr.Family > Right.Addr.Family;
      end if;

      pragma Assert (Socket_Stream < Socket_Datagram);
      --  To be sure that Mode_Type enumeration has appropriate elements order

      return Left.Mode < Right.Mode;
   end IPv6_TCP_Preferred;

   -------------------
   -- Get_Name_Info --
   -------------------

   function Get_Name_Info
     (Addr         : Sock_Addr_Type;
      Numeric_Host : Boolean := False;
      Numeric_Serv : Boolean := False) return Host_Service
   is
      SA  : aliased Sockaddr;
      H   : aliased C.char_array := (1 .. SOSC.NI_MAXHOST => C.nul);
      S   : aliased C.char_array := (1 .. SOSC.NI_MAXSERV => C.nul);
      RC  : C.int;
      Len : C.int;
   begin
      Set_Address (SA'Unchecked_Access, Addr, Len);

      RC := C_Getnameinfo
        (SA'Unchecked_Access, socklen_t (Len),
         H'Unchecked_Access, H'Length,
         S'Unchecked_Access, S'Length,
         (if Numeric_Host then SOSC.NI_NUMERICHOST else 0) +
             (if Numeric_Serv then SOSC.NI_NUMERICSERV else 0));

      if RC /= 0 then
         Raise_GAI_Error (RC, Image (Addr));
      end if;

      declare
         HR : constant String := C.To_Ada (H);
         SR : constant String := C.To_Ada (S);
      begin
         return (HR'Length, SR'Length, HR, SR);
      end;
   end Get_Name_Info;

   -------------------------
   -- Get_Host_By_Address --
   -------------------------

   function Get_Host_By_Address
     (Address : Inet_Addr_Type;
      Family  : Family_Type := Family_Inet) return Host_Entry_Type
   is
      pragma Unreferenced (Family);

      HA     : aliased In_Addr_Union (Address.Family);
      Buflen : constant C.size_t := Netdb_Buffer_Size;
      Buf    : aliased C.char_array (1 .. Netdb_Buffer_Size);
      Res    : aliased Hostent;
      Err    : aliased C.int;

   begin
      case Address.Family is
         when Family_Inet =>
            HA.In4 := To_In_Addr (Address);
         when Family_Inet6 =>
            HA.In6 := To_In6_Addr (Address);
      end case;

      Netdb_Lock;

      if C_Gethostbyaddr
        (HA'Address,
         (case Address.Family is
             when Family_Inet => HA.In4'Size,
             when Family_Inet6 => HA.In6'Size) / 8,
         Families (Address.Family),
         Res'Access, Buf'Address, Buflen, Err'Access) /= 0
      then
         Netdb_Unlock;
         Raise_Host_Error (Integer (Err), Image (Address));
      end if;

      begin
         return H : constant Host_Entry_Type :=
                      To_Host_Entry (Res'Unchecked_Access)
         do
            Netdb_Unlock;
         end return;
      exception
         when others =>
            Netdb_Unlock;
            raise;
      end;
   end Get_Host_By_Address;

   ----------------------
   -- Get_Host_By_Name --
   ----------------------

   function Get_Host_By_Name (Name : String) return Host_Entry_Type is
   begin
      --  If the given name actually is the string representation of
      --  an IP address, use Get_Host_By_Address instead.

      if Is_IPv4_Address (Name) or else Is_IPv6_Address (Name) then
         return Get_Host_By_Address (Inet_Addr (Name));
      end if;

      declare
         HN     : constant C.char_array := C.To_C (Name);
         Buflen : constant C.size_t := Netdb_Buffer_Size;
         Buf    : aliased C.char_array (1 .. Netdb_Buffer_Size);
         Res    : aliased Hostent;
         Err    : aliased C.int;

      begin
         Netdb_Lock;

         if C_Gethostbyname
           (HN, Res'Access, Buf'Address, Buflen, Err'Access) /= 0
         then
            Netdb_Unlock;
            Raise_Host_Error (Integer (Err), Name);
         end if;

         return H : constant Host_Entry_Type :=
                      To_Host_Entry (Res'Unchecked_Access)
         do
            Netdb_Unlock;
         end return;
      end;
   end Get_Host_By_Name;

   -------------------
   -- Get_Peer_Name --
   -------------------

   function Get_Peer_Name (Socket : Socket_Type) return Sock_Addr_Type is
      Sin : aliased Sockaddr;
      Len : aliased C.int := Sin'Size / 8;
   begin
      if C_Getpeername (C.int (Socket), Sin'Address, Len'Access) = Failure then
         Raise_Socket_Error (Socket_Errno);
      end if;

      return Get_Address (Sin, Len);
   end Get_Peer_Name;

   -------------------------
   -- Get_Service_By_Name --
   -------------------------

   function Get_Service_By_Name
     (Name     : String;
      Protocol : String) return Service_Entry_Type
   is
      SN     : constant C.char_array := C.To_C (Name);
      SP     : constant C.char_array := C.To_C (Protocol);
      Buflen : constant C.size_t := Netdb_Buffer_Size;
      Buf    : aliased C.char_array (1 .. Netdb_Buffer_Size);
      Res    : aliased Servent;

   begin
      Netdb_Lock;

      if C_Getservbyname (SN, SP, Res'Access, Buf'Address, Buflen) /= 0 then
         Netdb_Unlock;
         raise Service_Error with "Service not found";
      end if;

      --  Translate from the C format to the API format

      return S : constant Service_Entry_Type :=
                   To_Service_Entry (Res'Unchecked_Access)
      do
         Netdb_Unlock;
      end return;
   end Get_Service_By_Name;

   -------------------------
   -- Get_Service_By_Port --
   -------------------------

   function Get_Service_By_Port
     (Port     : Port_Type;
      Protocol : String) return Service_Entry_Type
   is
      SP     : constant C.char_array := C.To_C (Protocol);
      Buflen : constant C.size_t := Netdb_Buffer_Size;
      Buf    : aliased C.char_array (1 .. Netdb_Buffer_Size);
      Res    : aliased Servent;

   begin
      Netdb_Lock;

      if C_Getservbyport
        (C.int (Short_To_Network (C.unsigned_short (Port))), SP,
         Res'Access, Buf'Address, Buflen) /= 0
      then
         Netdb_Unlock;
         raise Service_Error with "Service not found";
      end if;

      --  Translate from the C format to the API format

      return S : constant Service_Entry_Type :=
                   To_Service_Entry (Res'Unchecked_Access)
      do
         Netdb_Unlock;
      end return;
   end Get_Service_By_Port;

   ---------------------
   -- Get_Socket_Name --
   ---------------------

   function Get_Socket_Name
     (Socket : Socket_Type) return Sock_Addr_Type
   is
      Sin : aliased Sockaddr;
      Len : aliased C.int := Sin'Size / 8;
      Res : C.int;
   begin
      Res := C_Getsockname (C.int (Socket), Sin'Address, Len'Access);

      if Res = Failure then
         return No_Sock_Addr;
      end if;

      return Get_Address (Sin, Len);
   end Get_Socket_Name;

   -----------------------
   -- Get_Socket_Option --
   -----------------------

   function Get_Socket_Option
     (Socket  : Socket_Type;
      Level   : Level_Type;
      Name    : Option_Name;
      Optname : Interfaces.C.int := -1) return Option_Type
   is
      use type C.unsigned;
      use type C.unsigned_char;

      V8  : aliased Two_Ints;
      V4  : aliased C.int;
      U4  : aliased C.unsigned;
      V1  : aliased C.unsigned_char;
      VT  : aliased Timeval;
      Len : aliased C.int;
      Add : System.Address;
      Res : C.int;
      Opt : Option_Type (Name);
      Onm : Interfaces.C.int;

   begin
      if Name in Specific_Option_Name then
         Onm := Options (Name);

      elsif Optname = -1 then
         raise Socket_Error with "optname must be specified";

      else
         Onm := Optname;
      end if;

      case Name is
         when Multicast_TTL
            | Receive_Packet_Info
         =>
            Len := V1'Size / 8;
            Add := V1'Address;

         when Broadcast
            | Busy_Polling
            | Error
            | Generic_Option
            | Keep_Alive
            | Keep_Alive_Count
            | Keep_Alive_Idle
            | Keep_Alive_Interval
            | Multicast_If_V4
            | Multicast_If_V6
            | Multicast_Loop_V4
            | Multicast_Loop_V6
            | Multicast_Hops
            | No_Delay
            | Receive_Buffer
            | Reuse_Address
            | Send_Buffer
            | IPv6_Only
         =>
            Len := V4'Size / 8;
            Add := V4'Address;

         when Receive_Timeout
            | Send_Timeout
         =>
            --  The standard argument for SO_RCVTIMEO and SO_SNDTIMEO is a
            --  struct timeval, but on Windows it is a milliseconds count in
            --  a DWORD.

            if Is_Windows then
               Len := U4'Size / 8;
               Add := U4'Address;
            else
               Len := VT'Size / 8;
               Add := VT'Address;
            end if;

         when Add_Membership_V4
            | Add_Membership_V6
            | Drop_Membership_V4
            | Drop_Membership_V6
         =>
            raise Socket_Error with
              "Add/Drop membership valid only for Set_Socket_Option";

         when Linger
         =>
            Len := V8'Size / 8;
            Add := V8'Address;
      end case;

      Res :=
        C_Getsockopt
          (C.int (Socket),
           Levels (Level),
           Onm,
           Add, Len'Access);

      if Res = Failure then
         Raise_Socket_Error (Socket_Errno);
      end if;

      case Name is
         when Generic_Option =>
            Opt.Optname := Onm;
            Opt.Optval  := V4;

         when Broadcast
            | Keep_Alive
            | No_Delay
            | Reuse_Address
            | Multicast_Loop_V4
            | Multicast_Loop_V6
            | IPv6_Only
         =>
            Opt.Enabled := (V4 /= 0);

         when Keep_Alive_Count =>
            Opt.Count := Natural (V4);

         when Keep_Alive_Idle =>
            Opt.Idle_Seconds := Natural (V4);

         when Keep_Alive_Interval =>
            Opt.Interval_Seconds := Natural (V4);

         when Busy_Polling =>
            Opt.Microseconds := Natural (V4);

         when Linger =>
            Opt.Enabled := (V8 (V8'First) /= 0);
            Opt.Seconds := Natural (V8 (V8'Last));

         when Receive_Buffer
            | Send_Buffer
         =>
            Opt.Size := Natural (V4);

         when Error =>
            Opt.Error := Resolve_Error (Integer (V4));

         when Add_Membership_V4
            | Add_Membership_V6
            | Drop_Membership_V4
            | Drop_Membership_V6
         =>
            --  No way to be here. Exception raised in the first case Name
            --  expression.
            null;

         when Multicast_If_V4 =>
            To_Inet_Addr (To_In_Addr (V4), Opt.Outgoing_If);

         when Multicast_If_V6 =>
            Opt.Outgoing_If_Index := Natural (V4);

         when Multicast_TTL =>
            Opt.Time_To_Live := Integer (V1);

         when Multicast_Hops =>
            Opt.Hop_Limit := Integer (V4);

         when Receive_Packet_Info
         =>
            Opt.Enabled := (V1 /= 0);

         when Receive_Timeout
            | Send_Timeout
         =>
            if Is_Windows then
               if U4 = 0 then
                  Opt.Timeout := 0.0;

               else
                  if Minus_500ms_Windows_Timeout then
                     --  Timeout is in milliseconds, actual value is 500 ms +
                     --  returned value (unless it is 0).

                     U4 := U4 + 500;
                  end if;

                  Opt.Timeout := Duration (U4) / 1000;
               end if;

            else
               Opt.Timeout := To_Duration (VT);
            end if;
      end case;

      return Opt;
   end Get_Socket_Option;

   ---------------
   -- Host_Name --
   ---------------

   function Host_Name return String is
      Name : aliased C.char_array (1 .. 64);
      Res  : C.int;

   begin
      Res := C_Gethostname (Name'Address, Name'Length);

      if Res = Failure then
         Raise_Socket_Error (Socket_Errno);
      end if;

      return C.To_Ada (Name);
   end Host_Name;

   -----------
   -- Image --
   -----------

   function Image (Value : Inet_Addr_Type) return String is
      use type CS.char_array_access;
      Size : constant socklen_t :=
        (case Value.Family is
            when Family_Inet   => 4 * Value.Sin_V4'Length,
            when Family_Inet6  => 6 * 5 + 4 * 4);
            --  1234:1234:1234:1234:1234:1234:123.123.123.123
      Dst : aliased C.char_array := (1 .. C.size_t (Size) => C.nul);
      Ia  : aliased In_Addr_Union (Value.Family);
   begin
      case Value.Family is
         when Family_Inet6 =>
            Ia.In6 := To_In6_Addr (Value);
         when Family_Inet =>
            Ia.In4 := To_In_Addr (Value);
      end case;

      if Inet_Ntop
        (Families (Value.Family), Ia'Address,
         Dst'Unchecked_Access, Size) = null
      then
         Raise_Socket_Error (Socket_Errno);
      end if;

      return C.To_Ada (Dst);
   end Image;

   -----------
   -- Image --
   -----------

   function Image (Value : Sock_Addr_Type) return String is
      function Ipv6_Brackets (S : String) return String is
        (if Value.Family = Family_Inet6 then "[" & S & "]" else S);
   begin
      case Value.Family is
         when Family_Unix =>
            if ASU.Length (Value.Name) > 0
              and then ASU.Element (Value.Name, 1) = ASCII.NUL
            then
               return '@' & ASU.Slice (Value.Name, 2, ASU.Length (Value.Name));
            else
               return ASU.To_String (Value.Name);
            end if;

         when Family_Inet_4_6 =>
            declare
               Port : constant String := Value.Port'Img;
            begin
               return Ipv6_Brackets (Image (Value.Addr)) & ':'
                 & Port (2 .. Port'Last);
            end;

         when Family_Unspec =>
            return "";
      end case;
   end Image;

   -----------
   -- Image --
   -----------

   function Image (Socket : Socket_Type) return String is
   begin
      return Socket'Img;
   end Image;

   -----------
   -- Image --
   -----------

   function Image (Item : Socket_Set_Type) return String is
      Socket_Set : Socket_Set_Type := Item;

   begin
      declare
         Last_Img : constant String := Socket_Set.Last'Img;
         Buffer   : String
                      (1 .. (Integer (Socket_Set.Last) + 1) * Last_Img'Length);
         Index    : Positive := 1;
         Socket   : Socket_Type;

      begin
         while not Is_Empty (Socket_Set) loop
            Get (Socket_Set, Socket);

            declare
               Socket_Img : constant String := Socket'Img;
            begin
               Buffer (Index .. Index + Socket_Img'Length - 1) := Socket_Img;
               Index := Index + Socket_Img'Length;
            end;
         end loop;

         return "[" & Last_Img & "]" & Buffer (1 .. Index - 1);
      end;
   end Image;

   ---------------
   -- Inet_Addr --
   ---------------

   function Inet_Addr (Image : String) return Inet_Addr_Type is
      use Interfaces.C;

      Img    : aliased char_array := To_C (Image);
      Res    : C.int;
      Result : Inet_Addr_Type;
      IPv6   : constant Boolean := Is_IPv6_Address (Image);
      Ia     : aliased In_Addr_Union
                 (if IPv6 then Family_Inet6 else Family_Inet);
   begin
      --  Special case for an empty Image as on some platforms (e.g. Windows)
      --  calling Inet_Addr("") will not return an error.

      if Image = "" then
         Raise_Socket_Error (SOSC.EINVAL);
      end if;

      Res := Inet_Pton
        ((if IPv6 then SOSC.AF_INET6 else SOSC.AF_INET), Img'Address,
         Ia'Address);

      if Res < 0 then
         Raise_Socket_Error (Socket_Errno);

      elsif Res = 0 then
         Raise_Socket_Error (SOSC.EINVAL);
      end if;

      if IPv6 then
         To_Inet_Addr (Ia.In6, Result);
      else
         To_Inet_Addr (Ia.In4, Result);
      end if;

      return Result;
   end Inet_Addr;

   ----------------
   -- Initialize --
   ----------------

   procedure Initialize (X : in out Sockets_Library_Controller) is
      pragma Unreferenced (X);

   begin
      Thin.Initialize;
   end Initialize;

   ----------------
   -- Initialize --
   ----------------

   procedure Initialize (Process_Blocking_IO : Boolean) is
      Expected : constant Boolean := not SOSC.Thread_Blocking_IO;

   begin
      if Process_Blocking_IO /= Expected then
         raise Socket_Error with
           "incorrect Process_Blocking_IO setting, expected " & Expected'Img;
      end if;

      --  This is a dummy placeholder for an obsolete API

      --  Real initialization actions are in Initialize primitive operation
      --  of Sockets_Library_Controller.

      null;
   end Initialize;

   ----------------
   -- Initialize --
   ----------------

   procedure Initialize is
   begin
      --  This is a dummy placeholder for an obsolete API

      --  Real initialization actions are in Initialize primitive operation
      --  of Sockets_Library_Controller.

      null;
   end Initialize;

   ----------------
   -- Is_Windows --
   ----------------

   function Is_Windows return Boolean is
      use SOSC;
   begin
      return Target_OS = Windows;
   end Is_Windows;

   --------------
   -- Is_Empty --
   --------------

   function Is_Empty (Item : Socket_Set_Type) return Boolean is
   begin
      return Item.Last = No_Socket;
   end Is_Empty;

   ---------------------
   -- Is_IPv6_Address --
   ---------------------

   function Is_IPv6_Address (Name : String) return Boolean is
      Prev_Colon   : Natural := 0;
      Double_Colon : Boolean := False;
      Colons       : Natural := 0;
   begin
      for J in Name'Range loop
         if Name (J) = ':' then
            Colons := Colons + 1;

            if Prev_Colon > 0 and then J = Prev_Colon + 1 then
               if Double_Colon then
                  --  Only one double colon allowed
                  return False;
               end if;

               Double_Colon := True;

            elsif J = Name'Last then
               --  Single colon at the end is not allowed
               return False;
            end if;

            Prev_Colon := J;

         elsif Prev_Colon = Name'First then
            --  Single colon at start is not allowed
            return False;

         elsif Name (J) = '.' then
            return Prev_Colon > 0
              and then Is_IPv4_Address (Name (Prev_Colon + 1 .. Name'Last));

         elsif Name (J) not in '0' .. '9' | 'A' .. 'F' | 'a' .. 'f' then
            return False;

         end if;
      end loop;

      return Colons in 2 .. 8;
   end Is_IPv6_Address;

   ---------------------
   -- Is_IPv4_Address --
   ---------------------

   function Is_IPv4_Address (Name : String) return Boolean is
      Dots : Natural := 0;

   begin
      --  Perform a cursory check for a dotted quad: we must have 1 to 3 dots,
      --  and there must be at least one digit around each.

      for J in Name'Range loop
         if Name (J) = '.' then

            --  Check that the dot is not in first or last position, and that
            --  it is followed by a digit. Note that we already know that it is
            --  preceded by a digit, or we would have returned earlier on.

            if J in Name'First + 1 .. Name'Last - 1
              and then Name (J + 1) in '0' .. '9'
            then
               Dots := Dots + 1;

            --  Definitely not a proper dotted quad

            else
               return False;
            end if;

         elsif Name (J) not in '0' .. '9' then
            return False;
         end if;
      end loop;

      return Dots in 1 .. 3;
   end Is_IPv4_Address;

   -------------
   -- Is_Open --
   -------------

   function Is_Open (S : Selector_Type) return Boolean is
   begin
      if S.Is_Null then
         return True;

      else
         --  Either both controlling socket descriptors are valid (case of an
         --  open selector) or neither (case of a closed selector).

         pragma Assert ((S.R_Sig_Socket /= No_Socket)
                          =
                        (S.W_Sig_Socket /= No_Socket));

         return S.R_Sig_Socket /= No_Socket;
      end if;
   end Is_Open;

   ------------
   -- Is_Set --
   ------------

   function Is_Set
     (Item   : Socket_Set_Type;
      Socket : Socket_Type) return Boolean
   is
   begin
      Check_For_Fd_Set (Socket);

      return Item.Last /= No_Socket
        and then Socket <= Item.Last
        and then Is_Socket_In_Set (Item.Set'Access, C.int (Socket)) /= 0;
   end Is_Set;

   -------------------
   -- Listen_Socket --
   -------------------

   procedure Listen_Socket
     (Socket : Socket_Type;
      Length : Natural := 15)
   is
      Res : constant C.int := C_Listen (C.int (Socket), C.int (Length));
   begin
      if Res = Failure then
         Raise_Socket_Error (Socket_Errno);
      end if;
   end Listen_Socket;

   ------------
   -- Narrow --
   ------------

   procedure Narrow (Item : in out Socket_Set_Type) is
      Last : aliased C.int := C.int (Item.Last);
   begin
      if Item.Last /= No_Socket then
         Last_Socket_In_Set (Item.Set'Access, Last'Unchecked_Access);
         Item.Last := Socket_Type (Last);
      end if;
   end Narrow;

   ----------------
   -- Netdb_Lock --
   ----------------

   procedure Netdb_Lock is
   begin
      if Need_Netdb_Lock then
         System.Task_Lock.Lock;
      end if;
   end Netdb_Lock;

   ------------------
   -- Netdb_Unlock --
   ------------------

   procedure Netdb_Unlock is
   begin
      if Need_Netdb_Lock then
         System.Task_Lock.Unlock;
      end if;
   end Netdb_Unlock;

   ----------------------------
   -- Network_Socket_Address --
   ----------------------------

   function Network_Socket_Address
     (Addr : Inet_Addr_Type; Port : Port_Type) return Sock_Addr_Type is
   begin
      return Result : Sock_Addr_Type (Addr.Family) do
         Result.Addr := Addr;
         Result.Port := Port;
      end return;
   end Network_Socket_Address;

   --------------------------------
   -- Normalize_Empty_Socket_Set --
   --------------------------------

   procedure Normalize_Empty_Socket_Set (S : in out Socket_Set_Type) is
   begin
      if S.Last = No_Socket then
         Reset_Socket_Set (S.Set'Access);
      end if;
   end Normalize_Empty_Socket_Set;

   -------------------
   -- Official_Name --
   -------------------

   function Official_Name (E : Host_Entry_Type) return String is
   begin
      return To_String (E.Official);
   end Official_Name;

   -------------------
   -- Official_Name --
   -------------------

   function Official_Name (S : Service_Entry_Type) return String is
   begin
      return To_String (S.Official);
   end Official_Name;

   --------------------
   -- Wait_On_Socket --
   --------------------

   procedure Wait_On_Socket
     (Socket   : Socket_Type;
      Event    : Poll.Wait_Event_Set;
      Timeout  : Selector_Duration;
      Selector : access Selector_Type := null;
      Status   : out Selector_Status)
   is
      Fd_Set : Poll.Set := Poll.To_Set (Socket, Event, 2);
      --  Socket itself and second place for signaling socket if necessary

      Count : Natural;
      Index : Natural := 0;

   begin
      --  Add signaling socket if selector defined

      if Selector /= null then
         Poll.Append (Fd_Set, Selector.R_Sig_Socket, Poll.Input_Event);
      end if;

      Poll.Wait (Fd_Set, Timeout, Count);

      if Count = 0 then
         Status := Expired;
      else
         Poll.Next (Fd_Set, Index);
         Status := (if Index = 1 then Completed else Aborted);
      end if;
   end Wait_On_Socket;

   -----------------
   -- Port_Number --
   -----------------

   function Port_Number (S : Service_Entry_Type) return Port_Type is
   begin
      return S.Port;
   end Port_Number;

   -------------------
   -- Protocol_Name --
   -------------------

   function Protocol_Name (S : Service_Entry_Type) return String is
   begin
      return To_String (S.Protocol);
   end Protocol_Name;

   ----------------------
   -- Raise_Host_Error --
   ----------------------

   procedure Raise_Host_Error (H_Error : Integer; Name : String) is
   begin
      raise Host_Error with
        Err_Code_Image (H_Error)
          & Dedot (Host_Error_Messages.Host_Error_Message (H_Error))
          & ": " & Name;
   end Raise_Host_Error;

   ------------------------
   -- Raise_Socket_Error --
   ------------------------

   procedure Raise_Socket_Error (Error : Integer) is
   begin
      raise Socket_Error with
        Err_Code_Image (Error) & Socket_Error_Message (Error);
   end Raise_Socket_Error;

   ----------
   -- Read --
   ----------

   procedure Read
     (Stream : in out Datagram_Socket_Stream_Type;
      Item   : out Ada.Streams.Stream_Element_Array;
      Last   : out Ada.Streams.Stream_Element_Offset)
   is
   begin
      Receive_Socket
        (Stream.Socket,
         Item,
         Last,
         Stream.From);
   end Read;

   ----------
   -- Read --
   ----------

   procedure Read
     (Stream : in out Stream_Socket_Stream_Type;
      Item   : out Ada.Streams.Stream_Element_Array;
      Last   : out Ada.Streams.Stream_Element_Offset)
   is
      First : Ada.Streams.Stream_Element_Offset          := Item'First;
      Index : Ada.Streams.Stream_Element_Offset          := First - 1;
      Max   : constant Ada.Streams.Stream_Element_Offset := Item'Last;

   begin
      loop
         Receive_Socket (Stream.Socket, Item (First .. Max), Index);
         Last  := Index;

         --  Exit when all or zero data received. Zero means that the socket
         --  peer is closed.

         exit when Index < First or else Index = Max;

         First := Index + 1;
      end loop;
   end Read;

   --------------------
   -- Receive_Socket --
   --------------------

   procedure Receive_Socket
     (Socket : Socket_Type;
      Item   : out Ada.Streams.Stream_Element_Array;
      Last   : out Ada.Streams.Stream_Element_Offset;
      Flags  : Request_Flag_Type := No_Request_Flag)
   is
      Res : C.int;

   begin
      Res :=
        C_Recv (C.int (Socket), Item'Address, Item'Length, To_Int (Flags));

      if Res = Failure then
         Raise_Socket_Error (Socket_Errno);
      end if;

      Last := Last_Index (First => Item'First, Count => size_t (Res));
   end Receive_Socket;

   --------------------
   -- Receive_Socket --
   --------------------

   procedure Receive_Socket
     (Socket : Socket_Type;
      Item   : out Ada.Streams.Stream_Element_Array;
      Last   : out Ada.Streams.Stream_Element_Offset;
      From   : out Sock_Addr_Type;
      Flags  : Request_Flag_Type := No_Request_Flag)
   is
      Res : C.int;
      Sin : aliased Sockaddr;
      Len : aliased C.int := Sin'Size / 8;

   begin
      Res :=
        C_Recvfrom
          (C.int (Socket),
           Item'Address,
           Item'Length,
           To_Int (Flags),
           Sin'Address,
           Len'Access);

      if Res = Failure then
         Raise_Socket_Error (Socket_Errno);
      end if;

      Last := Last_Index (First => Item'First, Count => size_t (Res));

      From := Get_Address (Sin, Len);
   end Receive_Socket;

   --------------------
   -- Receive_Vector --
   --------------------

   procedure Receive_Vector
     (Socket : Socket_Type;
      Vector : Vector_Type;
      Count  : out Ada.Streams.Stream_Element_Count;
      Flags  : Request_Flag_Type := No_Request_Flag)
   is
      Res : ssize_t;

      Msg : Msghdr :=
              (Msg_Name       => System.Null_Address,
               Msg_Namelen    => 0,
               Msg_Iov        => Vector'Address,

               --  recvmsg(2) returns EMSGSIZE on Linux (and probably on other
               --  platforms) when the supplied vector is longer than IOV_MAX,
               --  so use minimum of the two lengths.

               Msg_Iovlen     => SOSC.Msg_Iovlen_T'Min
                                   (Vector'Length, SOSC.IOV_MAX),

               Msg_Control    => System.Null_Address,
               Msg_Controllen => 0,
               Msg_Flags      => 0);

   begin
      Res :=
        C_Recvmsg
          (C.int (Socket),
           Msg'Address,
           To_Int (Flags));

      if Res = ssize_t (Failure) then
         Raise_Socket_Error (Socket_Errno);
      end if;

      Count := Ada.Streams.Stream_Element_Count (Res);
   end Receive_Vector;

   -------------------
   -- Resolve_Error --
   -------------------

   function Resolve_Error
     (Error_Value : Integer;
      From_Errno  : Boolean := True) return Error_Type
   is
      use GNAT.Sockets.SOSC;

   begin
      if not From_Errno then
         case Error_Value is
            when SOSC.HOST_NOT_FOUND => return Unknown_Host;
            when SOSC.TRY_AGAIN      => return Host_Name_Lookup_Failure;
            when SOSC.NO_RECOVERY    => return Non_Recoverable_Error;
            when SOSC.NO_DATA        => return Unknown_Server_Error;
            when others              => return Cannot_Resolve_Error;
         end case;
      end if;

      --  Special case: EAGAIN may be the same value as EWOULDBLOCK, so we
      --  can't include it in the case statement below.

      pragma Warnings (Off);
      --  Condition "EAGAIN /= EWOULDBLOCK" is known at compile time

      if EAGAIN /= EWOULDBLOCK and then Error_Value = EAGAIN then
         return Resource_Temporarily_Unavailable;
      end if;

      --  This is not a case statement because if a particular error
      --  number constant is not defined, s-oscons-tmplt.c defines
      --  it to -1.  If multiple constants are not defined, they
      --  would each be -1 and result in a "duplicate value in case" error.
      --
      --  But we have to leave warnings off because the compiler is also
      --  smart enough to note that when two errnos have the same value,
      --  the second if condition is useless.
      if Error_Value = ENOERROR then
         return Success;
      elsif Error_Value = EACCES then
         return Permission_Denied;
      elsif Error_Value = EADDRINUSE then
         return Address_Already_In_Use;
      elsif Error_Value = EADDRNOTAVAIL then
         return Cannot_Assign_Requested_Address;
      elsif Error_Value = EAFNOSUPPORT then
         return Address_Family_Not_Supported_By_Protocol;
      elsif Error_Value = EALREADY then
         return Operation_Already_In_Progress;
      elsif Error_Value = EBADF then
         return Bad_File_Descriptor;
      elsif Error_Value = ECONNABORTED then
         return Software_Caused_Connection_Abort;
      elsif Error_Value = ECONNREFUSED then
         return Connection_Refused;
      elsif Error_Value = ECONNRESET then
         return Connection_Reset_By_Peer;
      elsif Error_Value = EDESTADDRREQ then
         return Destination_Address_Required;
      elsif Error_Value = EFAULT then
         return Bad_Address;
      elsif Error_Value = EHOSTDOWN then
         return Host_Is_Down;
      elsif Error_Value = EHOSTUNREACH then
         return No_Route_To_Host;
      elsif Error_Value = EINPROGRESS then
         return Operation_Now_In_Progress;
      elsif Error_Value = EINTR then
         return Interrupted_System_Call;
      elsif Error_Value = EINVAL then
         return Invalid_Argument;
      elsif Error_Value = EIO then
         return Input_Output_Error;
      elsif Error_Value = EISCONN then
         return Transport_Endpoint_Already_Connected;
      elsif Error_Value = ELOOP then
         return Too_Many_Symbolic_Links;
      elsif Error_Value = EMFILE then
         return Too_Many_Open_Files;
      elsif Error_Value = EMSGSIZE then
         return Message_Too_Long;
      elsif Error_Value = ENAMETOOLONG then
         return File_Name_Too_Long;
      elsif Error_Value = ENETDOWN then
         return Network_Is_Down;
      elsif Error_Value = ENETRESET then
         return Network_Dropped_Connection_Because_Of_Reset;
      elsif Error_Value = ENETUNREACH then
         return Network_Is_Unreachable;
      elsif Error_Value = ENOBUFS then
         return No_Buffer_Space_Available;
      elsif Error_Value = ENOPROTOOPT then
         return Protocol_Not_Available;
      elsif Error_Value = ENOTCONN then
         return Transport_Endpoint_Not_Connected;
      elsif Error_Value = ENOTSOCK then
         return Socket_Operation_On_Non_Socket;
      elsif Error_Value = EOPNOTSUPP then
         return Operation_Not_Supported;
      elsif Error_Value = EPFNOSUPPORT then
         return Protocol_Family_Not_Supported;
      elsif Error_Value = EPIPE then
         return Broken_Pipe;
      elsif Error_Value = EPROTONOSUPPORT then
         return Protocol_Not_Supported;
      elsif Error_Value = EPROTOTYPE then
         return Protocol_Wrong_Type_For_Socket;
      elsif Error_Value = ESHUTDOWN then
         return Cannot_Send_After_Transport_Endpoint_Shutdown;
      elsif Error_Value = ESOCKTNOSUPPORT then
         return Socket_Type_Not_Supported;
      elsif Error_Value = ETIMEDOUT then
         return Connection_Timed_Out;
      elsif Error_Value = ETOOMANYREFS then
         return Too_Many_References;
      elsif Error_Value = EWOULDBLOCK then
         return Resource_Temporarily_Unavailable;
      else
         return Cannot_Resolve_Error;
      end if;
      pragma Warnings (On);

   end Resolve_Error;

   -----------------------
   -- Resolve_Exception --
   -----------------------

   function Resolve_Exception
     (Occurrence : Exception_Occurrence) return Error_Type
   is
      Id    : constant Exception_Id := Exception_Identity (Occurrence);
      Msg   : constant String       := Exception_Message (Occurrence);
      First : Natural;
      Last  : Natural;
      Val   : Integer;

   begin
      First := Msg'First;
      while First <= Msg'Last
        and then Msg (First) not in '0' .. '9'
      loop
         First := First + 1;
      end loop;

      if First > Msg'Last then
         return Cannot_Resolve_Error;
      end if;

      Last := First;
      while Last < Msg'Last
        and then Msg (Last + 1) in '0' .. '9'
      loop
         Last := Last + 1;
      end loop;

      Val := Integer'Value (Msg (First .. Last));

      if Id = Socket_Error_Id then
         return Resolve_Error (Val);

      elsif Id = Host_Error_Id then
         return Resolve_Error (Val, False);

      else
         return Cannot_Resolve_Error;
      end if;
   end Resolve_Exception;

   -----------------
   -- Send_Socket --
   -----------------

   procedure Send_Socket
     (Socket : Socket_Type;
      Item   : Ada.Streams.Stream_Element_Array;
      Last   : out Ada.Streams.Stream_Element_Offset;
      Flags  : Request_Flag_Type := No_Request_Flag)
   is
   begin
      Send_Socket (Socket, Item, Last, To => null, Flags => Flags);
   end Send_Socket;

   -----------------
   -- Send_Socket --
   -----------------

   procedure Send_Socket
     (Socket : Socket_Type;
      Item   : Ada.Streams.Stream_Element_Array;
      Last   : out Ada.Streams.Stream_Element_Offset;
      To     : Sock_Addr_Type;
      Flags  : Request_Flag_Type := No_Request_Flag)
   is
   begin
      Send_Socket
        (Socket, Item, Last, To => To'Unrestricted_Access, Flags => Flags);
   end Send_Socket;

   -----------------
   -- Send_Socket --
   -----------------

   procedure Send_Socket
     (Socket : Socket_Type;
      Item   : Ada.Streams.Stream_Element_Array;
      Last   : out Ada.Streams.Stream_Element_Offset;
      To     : access Sock_Addr_Type;
      Flags  : Request_Flag_Type := No_Request_Flag)
   is
      Res  : C.int;

      Sin  : aliased Sockaddr;
      C_To : System.Address;
      Len  : C.int;

   begin
      if To /= null then
         Set_Address (Sin'Unchecked_Access, To.all, Len);
         C_To := Sin'Address;

      else
         C_To := System.Null_Address;
         Len := 0;
      end if;

      Res := C_Sendto
        (C.int (Socket),
         Item'Address,
         Item'Length,
         Set_Forced_Flags (To_Int (Flags)),
         C_To,
         Len);

      if Res = Failure then
         Raise_Socket_Error (Socket_Errno);
      end if;

      Last := Last_Index (First => Item'First, Count => size_t (Res));
   end Send_Socket;

   -----------------
   -- Send_Vector --
   -----------------

   procedure Send_Vector
     (Socket : Socket_Type;
      Vector : Vector_Type;
      Count  : out Ada.Streams.Stream_Element_Count;
      Flags  : Request_Flag_Type := No_Request_Flag)
   is
      use Interfaces.C;

      Res            : ssize_t;
      Iov_Count      : SOSC.Msg_Iovlen_T;
      This_Iov_Count : SOSC.Msg_Iovlen_T;
      Msg            : Msghdr;

   begin
      Count := 0;
      Iov_Count := 0;
      while Iov_Count < Vector'Length loop

         pragma Warnings (Off);
         --  Following test may be compile time known on some targets

         This_Iov_Count :=
           (if Vector'Length - Iov_Count > SOSC.IOV_MAX
            then SOSC.IOV_MAX
            else Vector'Length - Iov_Count);

         pragma Warnings (On);

         Msg :=
           (Msg_Name       => System.Null_Address,
            Msg_Namelen    => 0,
            Msg_Iov        => Vector
                                (Vector'First + Integer (Iov_Count))'Address,
            Msg_Iovlen     => This_Iov_Count,
            Msg_Control    => System.Null_Address,
            Msg_Controllen => 0,
            Msg_Flags      => 0);

         Res :=
           C_Sendmsg
             (C.int (Socket),
              Msg'Address,
              Set_Forced_Flags (To_Int (Flags)));

         if Res = ssize_t (Failure) then
            Raise_Socket_Error (Socket_Errno);
         end if;

         Count := Count + Ada.Streams.Stream_Element_Count (Res);
         Iov_Count := Iov_Count + This_Iov_Count;
      end loop;
   end Send_Vector;

   ---------
   -- Set --
   ---------

   procedure Set (Item : in out Socket_Set_Type; Socket : Socket_Type) is
   begin
      Check_For_Fd_Set (Socket);

      if Item.Last = No_Socket then

         --  Uninitialized socket set, make sure it is properly zeroed out

         Reset_Socket_Set (Item.Set'Access);
         Item.Last := Socket;

      elsif Item.Last < Socket then
         Item.Last := Socket;
      end if;

      Insert_Socket_In_Set (Item.Set'Access, C.int (Socket));
   end Set;

   -----------------------
   -- Set_Close_On_Exec --
   -----------------------

   procedure Set_Close_On_Exec
     (Socket        : Socket_Type;
      Close_On_Exec : Boolean;
      Status        : out Boolean)
   is
      function C_Set_Close_On_Exec
        (Socket : Socket_Type; Close_On_Exec : C.int) return C.int;
      pragma Import (C, C_Set_Close_On_Exec, "__gnat_set_close_on_exec");
   begin
      Status := C_Set_Close_On_Exec (Socket, Boolean'Pos (Close_On_Exec)) = 0;
   end Set_Close_On_Exec;

   ----------------------
   -- Set_Forced_Flags --
   ----------------------

   function Set_Forced_Flags (F : C.int) return C.int is
      use type C.unsigned;
      function To_unsigned is
        new Ada.Unchecked_Conversion (C.int, C.unsigned);
      function To_int is
        new Ada.Unchecked_Conversion (C.unsigned, C.int);
   begin
      return To_int (To_unsigned (F) or SOSC.MSG_Forced_Flags);
   end Set_Forced_Flags;

   -----------------------
   -- Set_Socket_Option --
   -----------------------

   procedure Set_Socket_Option
     (Socket : Socket_Type;
      Level  : Level_Type;
      Option : Option_Type)
   is
      use type C.unsigned;

      MR  : aliased IPV6_Mreq;
      V8  : aliased Two_Ints;
      V4  : aliased C.int;
      U4  : aliased C.unsigned;
      V1  : aliased C.unsigned_char;
      VT  : aliased Timeval;
      Len : C.int;
      Add : System.Address := Null_Address;
      Res : C.int;
      Onm : C.int;

   begin
      case Option.Name is
         when Generic_Option =>
            V4  := Option.Optval;
            Len := V4'Size / 8;
            Add := V4'Address;

         when Broadcast
            | Keep_Alive
            | No_Delay
            | Reuse_Address
            | Multicast_Loop_V4
            | Multicast_Loop_V6
            | IPv6_Only
         =>
            V4  := C.int (Boolean'Pos (Option.Enabled));
            Len := V4'Size / 8;
            Add := V4'Address;

         when Keep_Alive_Count =>
            V4  := C.int (Option.Count);
            Len := V4'Size / 8;
            Add := V4'Address;

         when Keep_Alive_Idle =>
            V4  := C.int (Option.Idle_Seconds);
            Len := V4'Size / 8;
            Add := V4'Address;

         when Keep_Alive_Interval =>
            V4  := C.int (Option.Interval_Seconds);
            Len := V4'Size / 8;
            Add := V4'Address;

         when Busy_Polling =>
            V4  := C.int (Option.Microseconds);
            Len := V4'Size / 8;
            Add := V4'Address;

         when Linger =>
            V8 (V8'First) := C.int (Boolean'Pos (Option.Enabled));
            V8 (V8'Last)  := C.int (Option.Seconds);
            Len := V8'Size / 8;
            Add := V8'Address;

         when Receive_Buffer
            | Send_Buffer
         =>
            V4  := C.int (Option.Size);
            Len := V4'Size / 8;
            Add := V4'Address;

         when Error =>
            V4  := C.int (Boolean'Pos (True));
            Len := V4'Size / 8;
            Add := V4'Address;

         when Add_Membership_V4
            | Drop_Membership_V4
         =>
            V8 (V8'First) := To_Int (To_In_Addr (Option.Multicast_Address));
            V8 (V8'Last)  := To_Int (To_In_Addr (Option.Local_Interface));
            Len := V8'Size / 8;
            Add := V8'Address;

         when Add_Membership_V6
            | Drop_Membership_V6 =>
            MR.ipv6mr_multiaddr := To_In6_Addr (Option.Multicast_Address);
            MR.ipv6mr_interface := C.unsigned (Option.Interface_Index);
            Len := MR'Size / 8;
            Add := MR'Address;

         when Multicast_If_V4 =>
            V4  := To_Int (To_In_Addr (Option.Outgoing_If));
            Len := V4'Size / 8;
            Add := V4'Address;

         when Multicast_If_V6 =>
            V4  := C.int (Option.Outgoing_If_Index);
            Len := V4'Size / 8;
            Add := V4'Address;

         when Multicast_TTL =>
            V1  := C.unsigned_char (Option.Time_To_Live);
            Len := V1'Size / 8;
            Add := V1'Address;

         when Multicast_Hops =>
            V4  := C.int (Option.Hop_Limit);
            Len := V4'Size / 8;
            Add := V4'Address;

         when Receive_Packet_Info
         =>
            V1  := C.unsigned_char (Boolean'Pos (Option.Enabled));
            Len := V1'Size / 8;
            Add := V1'Address;

         when Receive_Timeout
            | Send_Timeout
         =>
            if Is_Windows then

               --  On Windows, the timeout is a DWORD in milliseconds

               Len := U4'Size / 8;
               Add := U4'Address;

               U4 := C.unsigned (Option.Timeout * 1000);

               if Option.Timeout > 0.0 and then U4 = 0 then
                  --  Avoid round to zero. Zero timeout mean unlimited
                  U4 := 1;
               end if;

               --  Old windows versions actual timeout is 500 ms + the given
               --  value (unless it is 0).

               if Minus_500ms_Windows_Timeout then
                  if U4 > 500 then
                     U4 := U4 - 500;

                  elsif U4 > 0 then
                     U4 := 1;
                  end if;
               end if;

            else
               VT  := To_Timeval (Option.Timeout);
               Len := VT'Size / 8;
               Add := VT'Address;
            end if;
      end case;

      if Option.Name in Specific_Option_Name then
         Onm := Options (Option.Name);

      elsif Option.Optname = -1 then
         raise Socket_Error with "optname must be specified";

      else
         Onm := Option.Optname;
      end if;

      Res := C_Setsockopt
        (C.int (Socket),
         Levels (Level),
         Onm,
         Add, Len);

      if Res = Failure then
         Raise_Socket_Error (Socket_Errno);
      end if;
   end Set_Socket_Option;

   ---------------------
   -- Shutdown_Socket --
   ---------------------

   procedure Shutdown_Socket
     (Socket : Socket_Type;
      How    : Shutmode_Type := Shut_Read_Write)
   is
      Res : C.int;

   begin
      Res := C_Shutdown (C.int (Socket), Shutmodes (How));

      if Res = Failure then
         Raise_Socket_Error (Socket_Errno);
      end if;
   end Shutdown_Socket;

   ------------
   -- Stream --
   ------------

   function Stream
     (Socket  : Socket_Type;
      Send_To : Sock_Addr_Type) return Stream_Access
   is
      S : Datagram_Socket_Stream_Access;

   begin
      S        := new Datagram_Socket_Stream_Type;
      S.Socket := Socket;
      S.To     := Send_To;
      S.From   := Get_Socket_Name (Socket);
      return Stream_Access (S);
   end Stream;

   ------------
   -- Stream --
   ------------

   function Stream (Socket : Socket_Type) return Stream_Access is
      S : Stream_Socket_Stream_Access;
   begin
      S := new Stream_Socket_Stream_Type;
      S.Socket := Socket;
      return Stream_Access (S);
   end Stream;

   ------------
   -- To_Ada --
   ------------

   function To_Ada (Fd : Integer) return Socket_Type is
   begin
      return Socket_Type (Fd);
   end To_Ada;

   ----------
   -- To_C --
   ----------

   function To_C (Socket : Socket_Type) return Integer is
   begin
      return Integer (Socket);
   end To_C;

   -----------------
   -- To_Duration --
   -----------------

   function To_Duration (Val : Timeval) return Timeval_Duration is
      Max_D : constant Long_Long_Integer := Long_Long_Integer (Forever - 0.5);
      Tv_sec_64 : constant Boolean := SOSC.SIZEOF_tv_sec = 8;
      --  Need to separate this condition into the constant declaration to
      --  avoid GNAT warning about "always true" or "always false".
   begin
      if Tv_sec_64 then
         --  Check for possible Duration overflow when Tv_Sec field is 64 bit
         --  integer.

         if Val.Tv_Sec > time_t (Max_D)
             or else
           (Val.Tv_Sec = time_t (Max_D)
              and then
            Val.Tv_Usec > suseconds_t ((Forever - Duration (Max_D)) * 1E6))
         then
            return Forever;
         end if;
      end if;

      return Duration (Val.Tv_Sec) + Duration (Val.Tv_Usec) * 1.0E-6;
   end To_Duration;

   -------------------
   -- To_Host_Entry --
   -------------------

   function To_Host_Entry (E : Hostent_Access) return Host_Entry_Type is
      Aliases_Count, Addresses_Count : Natural;

      Family : constant Family_Type :=
                 (case Hostent_H_Addrtype (E) is
                     when SOSC.AF_INET  => Family_Inet,
                     when SOSC.AF_INET6 => Family_Inet6,
                     when others        => Family_Unspec);

      Addr_Len : constant C.size_t := C.size_t (Hostent_H_Length (E));

   begin
      if Family = Family_Unspec then
         Raise_Socket_Error (SOSC.EPFNOSUPPORT);
      end if;

      Aliases_Count := 0;
      while Hostent_H_Alias (E, C.int (Aliases_Count)) /= Null_Address loop
         Aliases_Count := Aliases_Count + 1;
      end loop;

      Addresses_Count := 0;
      while Hostent_H_Addr (E, C.int (Addresses_Count)) /= Null_Address loop
         Addresses_Count := Addresses_Count + 1;
      end loop;

      return Result : Host_Entry_Type
                        (Aliases_Length   => Aliases_Count,
                         Addresses_Length => Addresses_Count)
      do
         Result.Official := To_Name (Value (Hostent_H_Name (E)));

         for J in Result.Aliases'Range loop
            Result.Aliases (J) :=
              To_Name (Value (Hostent_H_Alias
                                (E, C.int (J - Result.Aliases'First))));
         end loop;

         for J in Result.Addresses'Range loop
            declare
               Ia : In_Addr_Union (Family);

               --  Hostent_H_Addr (E, <index>) may return an address that is
               --  not correctly aligned for In_Addr, so we need to use
               --  an intermediate copy operation on a type with an alignment
               --  of 1 to recover the value.

               subtype Addr_Buf_T is C.char_array (1 .. Addr_Len);
               Unaligned_Addr : Addr_Buf_T;
               for Unaligned_Addr'Address
                 use Hostent_H_Addr (E, C.int (J - Result.Addresses'First));
               pragma Import (Ada, Unaligned_Addr);

               Aligned_Addr : Addr_Buf_T;
               for Aligned_Addr'Address use Ia'Address;
               pragma Import (Ada, Aligned_Addr);

            begin
               Aligned_Addr := Unaligned_Addr;
               if Family = Family_Inet6 then
                  To_Inet_Addr (Ia.In6, Result.Addresses (J));
               else
                  To_Inet_Addr (Ia.In4, Result.Addresses (J));
               end if;
            end;
         end loop;
      end return;
   end To_Host_Entry;

   ------------
   -- To_Int --
   ------------

   function To_Int (F : Request_Flag_Type) return C.int is
      Current : Request_Flag_Type := F;
      Result  : C.int := 0;

   begin
      for J in Flags'Range loop
         exit when Current = 0;

         if Current mod 2 /= 0 then
            if Flags (J) = -1 then
               pragma Annotate
                 (CodePeer, False_Positive,
                  "test always false", "self fulfilling prophecy");

               Raise_Socket_Error (SOSC.EOPNOTSUPP);
            end if;

            Result := Result + Flags (J);
         end if;

         Current := Current / 2;
      end loop;

      return Result;
   end To_Int;

   -------------
   -- To_Name --
   -------------

   function To_Name (N : String) return Name_Type is
   begin
      return Name_Type'(N'Length, N);
   end To_Name;

   ----------------------
   -- To_Service_Entry --
   ----------------------

   function To_Service_Entry (E : Servent_Access) return Service_Entry_Type is
      Aliases_Count : Natural;

   begin
      Aliases_Count := 0;
      while Servent_S_Alias (E, C.int (Aliases_Count)) /= Null_Address loop
         Aliases_Count := Aliases_Count + 1;
      end loop;

      return Result : Service_Entry_Type (Aliases_Length   => Aliases_Count) do
         Result.Official := To_Name (Value (Servent_S_Name (E)));

         for J in Result.Aliases'Range loop
            Result.Aliases (J) :=
              To_Name (Value (Servent_S_Alias
                                (E, C.int (J - Result.Aliases'First))));
         end loop;

         Result.Protocol := To_Name (Value (Servent_S_Proto (E)));
         Result.Port :=
           Port_Type (Network_To_Short (Servent_S_Port (E)));
      end return;
   end To_Service_Entry;

   ---------------
   -- To_String --
   ---------------

   function To_String (HN : Name_Type) return String is
   begin
      return HN.Name (1 .. HN.Length);
   end To_String;

   ----------------
   -- To_Timeval --
   ----------------

   function To_Timeval (Val : Timeval_Duration) return Timeval is
      S  : time_t;
      uS : suseconds_t;

   begin
      --  If zero, set result as zero (otherwise it gets rounded down to -1)

      if Val = 0.0 then
         S  := 0;
         uS := 0;

      --  Normal case where we do round down

      else
         S  := time_t (Val - 0.5);
         uS := suseconds_t (1_000_000 * (Val - Selector_Duration (S)) - 0.5);

         if uS = -1 then
            --  It happen on integer duration
            uS := 0;
         end if;
      end if;

      return (S, uS);
   end To_Timeval;

   -----------
   -- Value --
   -----------

   function Value (S : System.Address) return String is
      Str : String (1 .. Positive'Last);
      for Str'Address use S;
      pragma Import (Ada, Str);

      Terminator : Positive := Str'First;

   begin
      while Str (Terminator) /= ASCII.NUL loop
         Terminator := Terminator + 1;
      end loop;

      return Str (1 .. Terminator - 1);
   end Value;

   -----------
   -- Write --
   -----------

   procedure Write
     (Stream : in out Datagram_Socket_Stream_Type;
      Item   : Ada.Streams.Stream_Element_Array)
   is
      Last : Stream_Element_Offset;

   begin
      Send_Socket
        (Stream.Socket,
         Item,
         Last,
         Stream.To);

      --  It is an error if not all of the data has been sent

      if Last /= Item'Last then
         Raise_Socket_Error (Socket_Errno);
      end if;
   end Write;

   -----------
   -- Write --
   -----------

   procedure Write
     (Stream : in out Stream_Socket_Stream_Type;
      Item   : Ada.Streams.Stream_Element_Array)
   is
      First : Ada.Streams.Stream_Element_Offset;
      Index : Ada.Streams.Stream_Element_Offset;
      Max   : constant Ada.Streams.Stream_Element_Offset := Item'Last;

   begin
      First := Item'First;
      Index := First - 1;
      while First <= Max loop
         Send_Socket (Stream.Socket, Item (First .. Max), Index, null);

         --  Exit when all or zero data sent. Zero means that the socket has
         --  been closed by peer.

         exit when Index < First or else Index = Max;

         First := Index + 1;
      end loop;

      --  For an empty array, we have First > Max, and hence Index >= Max (no
      --  error, the loop above is never executed). After a successful send,
      --  Index = Max. The only remaining case, Index < Max, is therefore
      --  always an actual send failure.

      if Index < Max then
         Raise_Socket_Error (Socket_Errno);
      end if;
   end Write;

   Sockets_Library_Controller_Object : Sockets_Library_Controller;
   pragma Unreferenced (Sockets_Library_Controller_Object);
   --  The elaboration and finalization of this object perform the required
   --  initialization and cleanup actions for the sockets library.

   --------------------
   -- Create_Address --
   --------------------

   function Create_Address
     (Family : Family_Inet_4_6; Bytes : Inet_Addr_Bytes) return Inet_Addr_Type
   is
     (case Family is
         when Family_Inet => (Family_Inet, Bytes),
         when Family_Inet6 => (Family_Inet6, Bytes));

   ---------------
   -- Get_Bytes --
   ---------------

   function Get_Bytes (Addr : Inet_Addr_Type) return Inet_Addr_Bytes is
     (case Addr.Family is
         when Family_Inet => Addr.Sin_V4,
         when Family_Inet6 => Addr.Sin_V6);

   ----------
   -- Mask --
   ----------

   function Mask
     (Family : Family_Inet_4_6;
      Length : Natural;
      Host   : Boolean := False) return Inet_Addr_Type
   is
      Addr_Len : constant Natural := Inet_Addr_Bytes_Length (Family);
   begin
      if Length > 8 * Addr_Len then
         raise Constraint_Error with
           "invalid mask length for address family " & Family'Img;
      end if;

      declare
         B    : Inet_Addr_Bytes (1 ..  Addr_Len);
         Part : Inet_Addr_Comp_Type;
      begin
         for J in 1 .. Length / 8 loop
            B (J) := (if Host then 0 else 255);
         end loop;

         if Length < 8 * Addr_Len then
            Part := 2 ** (8 - Length mod 8) - 1;
            B (Length / 8 + 1) := (if Host then Part else not Part);

            for J in Length / 8 + 2 .. B'Last loop
               B (J) := (if Host then 255 else 0);
            end loop;
         end if;

         return Create_Address (Family, B);
      end;
   end Mask;

   -------------------------
   -- Unix_Socket_Address --
   -------------------------

   function Unix_Socket_Address (Addr : String) return Sock_Addr_Type is
   begin
      return Sock_Addr_Type'(Family_Unix, ASU.To_Unbounded_String (Addr));
   end Unix_Socket_Address;

   -----------
   -- "and" --
   -----------

   function "and" (Addr, Mask : Inet_Addr_Type) return Inet_Addr_Type is
   begin
      if Addr.Family /= Mask.Family then
         raise Constraint_Error with "incompatible address families";
      end if;

      declare
         A : constant Inet_Addr_Bytes := Get_Bytes (Addr);
         M : constant Inet_Addr_Bytes := Get_Bytes (Mask);
         R : Inet_Addr_Bytes (A'Range);

      begin
         for J in A'Range loop
            R (J) := A (J) and M (J);
         end loop;
         return Create_Address (Addr.Family, R);
      end;
   end "and";

   ----------
   -- "or" --
   ----------

   function "or" (Net, Host : Inet_Addr_Type) return Inet_Addr_Type is
   begin
      if Net.Family /= Host.Family then
         raise Constraint_Error with "incompatible address families";
      end if;

      declare
         N : constant Inet_Addr_Bytes := Get_Bytes (Net);
         H : constant Inet_Addr_Bytes := Get_Bytes (Host);
         R : Inet_Addr_Bytes (N'Range);

      begin
         for J in N'Range loop
            R (J) := N (J) or H (J);
         end loop;
         return Create_Address (Net.Family, R);
      end;
   end "or";

   -----------
   -- "not" --
   -----------

   function "not" (Mask : Inet_Addr_Type) return Inet_Addr_Type is
      M : constant Inet_Addr_Bytes := Get_Bytes (Mask);
      R : Inet_Addr_Bytes (M'Range);
   begin
      for J in R'Range loop
         R (J) := not M (J);
      end loop;
      return Create_Address (Mask.Family, R);
   end "not";

end GNAT.Sockets;
