File : g-sothco.ads


   1 ------------------------------------------------------------------------------
   2 --                                                                          --
   3 --                         GNAT COMPILER COMPONENTS                         --
   4 --                                                                          --
   5 --              G N A T . S O C K E T S . T H I N _ C O M M O N             --
   6 --                                                                          --
   7 --                                 S p e c                                  --
   8 --                                                                          --
   9 --                     Copyright (C) 2008-2014, AdaCore                     --
  10 --                                                                          --
  11 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
  12 -- terms of the  GNU General Public License as published  by the Free Soft- --
  13 -- ware  Foundation;  either version 3,  or (at your option) any later ver- --
  14 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
  15 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
  16 -- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
  17 --                                                                          --
  18 --                                                                          --
  19 --                                                                          --
  20 --                                                                          --
  21 --                                                                          --
  22 -- You should have received a copy of the GNU General Public License and    --
  23 -- a copy of the GCC Runtime Library Exception along with this program;     --
  24 -- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
  25 -- <http://www.gnu.org/licenses/>.                                          --
  26 --                                                                          --
  27 -- GNAT was originally developed  by the GNAT team at  New York University. --
  28 -- Extensive contributions were provided by Ada Core Technologies Inc.      --
  29 --                                                                          --
  30 ------------------------------------------------------------------------------
  31 
  32 --  This is the target-independent part of the thin sockets mapping.
  33 --  This package should not be directly with'ed by an applications program.
  34 
  35 with Ada.Unchecked_Conversion;
  36 
  37 with Interfaces.C;
  38 with Interfaces.C.Pointers;
  39 
  40 package GNAT.Sockets.Thin_Common is
  41 
  42    package C renames Interfaces.C;
  43 
  44    use type C.int;
  45    --  This is so we can declare the Failure constant below
  46 
  47    Success : constant C.int :=  0;
  48    Failure : constant C.int := -1;
  49 
  50    type time_t is
  51      range -2 ** (8 * SOSC.SIZEOF_tv_sec - 1)
  52          .. 2 ** (8 * SOSC.SIZEOF_tv_sec - 1) - 1;
  53    for time_t'Size use 8 * SOSC.SIZEOF_tv_sec;
  54    pragma Convention (C, time_t);
  55 
  56    type suseconds_t is
  57      range -2 ** (8 * SOSC.SIZEOF_tv_usec - 1)
  58          .. 2 ** (8 * SOSC.SIZEOF_tv_usec - 1) - 1;
  59    for suseconds_t'Size use 8 * SOSC.SIZEOF_tv_usec;
  60    pragma Convention (C, suseconds_t);
  61 
  62    type Timeval is record
  63       Tv_Sec  : time_t;
  64       Tv_Usec : suseconds_t;
  65    end record;
  66    pragma Convention (C, Timeval);
  67 
  68    type Timeval_Access is access all Timeval;
  69    pragma Convention (C, Timeval_Access);
  70 
  71    Immediat : constant Timeval := (0, 0);
  72 
  73    -------------------------------------------
  74    -- Mapping tables to low level constants --
  75    -------------------------------------------
  76 
  77    Families : constant array (Family_Type) of C.int :=
  78                 (Family_Inet  => SOSC.AF_INET,
  79                  Family_Inet6 => SOSC.AF_INET6);
  80 
  81    Lengths  : constant array (Family_Type) of C.unsigned_char :=
  82                 (Family_Inet  => SOSC.SIZEOF_sockaddr_in,
  83                  Family_Inet6 => SOSC.SIZEOF_sockaddr_in6);
  84 
  85    ----------------------------
  86    -- Generic socket address --
  87    ----------------------------
  88 
  89    --  Common header
  90 
  91    --  All socket address types (struct sockaddr, struct sockaddr_storage,
  92    --  and protocol specific address types) start with the same 2-byte header,
  93    --  which is either a length and a family (one byte each) or just a two-byte
  94    --  family. The following unchecked union describes the two possible layouts
  95    --  and is meant to be constrained with SOSC.Have_Sockaddr_Len.
  96 
  97    type Sockaddr_Length_And_Family
  98      (Has_Sockaddr_Len : Boolean := False)
  99    is record
 100       case Has_Sockaddr_Len is
 101          when True =>
 102             Length      : C.unsigned_char;
 103             Char_Family : C.unsigned_char;
 104 
 105          when False =>
 106             Short_Family : C.unsigned_short;
 107       end case;
 108    end record;
 109    pragma Unchecked_Union (Sockaddr_Length_And_Family);
 110    pragma Convention (C, Sockaddr_Length_And_Family);
 111 
 112    procedure Set_Family
 113      (Length_And_Family : out Sockaddr_Length_And_Family;
 114       Family            : Family_Type);
 115    --  Set the family component to the appropriate value for Family, and also
 116    --  set Length accordingly if applicable on this platform.
 117 
 118    type Sockaddr is record
 119       Sa_Family : Sockaddr_Length_And_Family;
 120       --  Address family (and address length on some platforms)
 121 
 122       Sa_Data : C.char_array (1 .. 14) := (others => C.nul);
 123       --  Family-specific data
 124       --  Note that some platforms require that all unused (reserved) bytes
 125       --  in addresses be initialized to 0 (e.g. VxWorks).
 126    end record;
 127    pragma Convention (C, Sockaddr);
 128    --  Generic socket address
 129 
 130    type Sockaddr_Access is access all Sockaddr;
 131    pragma Convention (C, Sockaddr_Access);
 132    --  Access to socket address
 133 
 134    ----------------------------
 135    -- AF_INET socket address --
 136    ----------------------------
 137 
 138    type In_Addr is record
 139       S_B1, S_B2, S_B3, S_B4 : C.unsigned_char;
 140    end record;
 141    for In_Addr'Alignment use C.int'Alignment;
 142    pragma Convention (C, In_Addr);
 143    --  IPv4 address, represented as a network-order C.int. Note that the
 144    --  underlying operating system may assume that values of this type have
 145    --  C.int alignment, so we need to provide a suitable alignment clause here.
 146 
 147    function To_In_Addr is new Ada.Unchecked_Conversion (C.int, In_Addr);
 148    function To_Int     is new Ada.Unchecked_Conversion (In_Addr, C.int);
 149 
 150    type In_Addr_Access is access all In_Addr;
 151    pragma Convention (C, In_Addr_Access);
 152    --  Access to internet address
 153 
 154    Inaddr_Any : aliased constant In_Addr := (others => 0);
 155    --  Any internet address (all the interfaces)
 156 
 157    type In_Addr_Access_Array is array (C.size_t range <>)
 158      of aliased In_Addr_Access;
 159    pragma Convention (C, In_Addr_Access_Array);
 160 
 161    package In_Addr_Access_Pointers is new C.Pointers
 162      (C.size_t, In_Addr_Access, In_Addr_Access_Array, null);
 163    --  Array of internet addresses
 164 
 165    type Sockaddr_In is record
 166       Sin_Family : Sockaddr_Length_And_Family;
 167       --  Address family (and address length on some platforms)
 168 
 169       Sin_Port : C.unsigned_short;
 170       --  Port in network byte order
 171 
 172       Sin_Addr : In_Addr;
 173       --  IPv4 address
 174 
 175       Sin_Zero : C.char_array (1 .. 8) := (others => C.nul);
 176       --  Padding
 177       --
 178       --  Note that some platforms require that all unused (reserved) bytes
 179       --  in addresses be initialized to 0 (e.g. VxWorks).
 180    end record;
 181    pragma Convention (C, Sockaddr_In);
 182    --  Internet socket address
 183 
 184    type Sockaddr_In_Access is access all Sockaddr_In;
 185    pragma Convention (C, Sockaddr_In_Access);
 186    --  Access to internet socket address
 187 
 188    procedure Set_Port
 189      (Sin  : Sockaddr_In_Access;
 190       Port : C.unsigned_short);
 191    pragma Inline (Set_Port);
 192    --  Set Sin.Sin_Port to Port
 193 
 194    procedure Set_Address
 195      (Sin     : Sockaddr_In_Access;
 196       Address : In_Addr);
 197    pragma Inline (Set_Address);
 198    --  Set Sin.Sin_Addr to Address
 199 
 200    ------------------
 201    -- Host entries --
 202    ------------------
 203 
 204    type Hostent is new
 205      System.Storage_Elements.Storage_Array (1 .. SOSC.SIZEOF_struct_hostent);
 206    for Hostent'Alignment use 8;
 207    --  Host entry. This is an opaque type used only via the following
 208    --  accessor functions, because 'struct hostent' has different layouts on
 209    --  different platforms.
 210 
 211    type Hostent_Access is access all Hostent;
 212    pragma Convention (C, Hostent_Access);
 213    --  Access to host entry
 214 
 215    function Hostent_H_Name
 216      (E : Hostent_Access) return System.Address;
 217 
 218    function Hostent_H_Alias
 219      (E : Hostent_Access; I : C.int) return System.Address;
 220 
 221    function Hostent_H_Addrtype
 222      (E : Hostent_Access) return C.int;
 223 
 224    function Hostent_H_Length
 225      (E : Hostent_Access) return C.int;
 226 
 227    function Hostent_H_Addr
 228      (E : Hostent_Access; Index : C.int) return System.Address;
 229 
 230    ---------------------
 231    -- Service entries --
 232    ---------------------
 233 
 234    type Servent is new
 235      System.Storage_Elements.Storage_Array (1 .. SOSC.SIZEOF_struct_servent);
 236    for Servent'Alignment use 8;
 237    --  Service entry. This is an opaque type used only via the following
 238    --  accessor functions, because 'struct servent' has different layouts on
 239    --  different platforms.
 240 
 241    type Servent_Access is access all Servent;
 242    pragma Convention (C, Servent_Access);
 243    --  Access to service entry
 244 
 245    function Servent_S_Name
 246      (E : Servent_Access) return System.Address;
 247 
 248    function Servent_S_Alias
 249      (E : Servent_Access; Index : C.int) return System.Address;
 250 
 251    function Servent_S_Port
 252      (E : Servent_Access) return C.unsigned_short;
 253 
 254    function Servent_S_Proto
 255      (E : Servent_Access) return System.Address;
 256 
 257    ------------------
 258    -- NetDB access --
 259    ------------------
 260 
 261    --  There are three possible situations for the following NetDB access
 262    --  functions:
 263    --    - inherently thread safe (case of data returned in a thread specific
 264    --      buffer);
 265    --    - thread safe using user-provided buffer;
 266    --    - thread unsafe.
 267    --
 268    --  In the first and third cases, the Buf and Buflen are ignored. In the
 269    --  second case, the caller must provide a buffer large enough to
 270    --  accommodate the returned data. In the third case, the caller must ensure
 271    --  that these functions are called within a critical section.
 272 
 273    function C_Gethostbyname
 274      (Name     : C.char_array;
 275       Ret      : not null access Hostent;
 276       Buf      : System.Address;
 277       Buflen   : C.int;
 278       H_Errnop : not null access C.int) return C.int;
 279 
 280    function C_Gethostbyaddr
 281      (Addr      : System.Address;
 282       Addr_Len  : C.int;
 283       Addr_Type : C.int;
 284       Ret       : not null access Hostent;
 285       Buf       : System.Address;
 286       Buflen    : C.int;
 287       H_Errnop  : not null access C.int) return C.int;
 288 
 289    function C_Getservbyname
 290      (Name   : C.char_array;
 291       Proto  : C.char_array;
 292       Ret    : not null access Servent;
 293       Buf    : System.Address;
 294       Buflen : C.int) return C.int;
 295 
 296    function C_Getservbyport
 297      (Port   : C.int;
 298       Proto  : C.char_array;
 299       Ret    : not null access Servent;
 300       Buf    : System.Address;
 301       Buflen : C.int) return C.int;
 302 
 303    ------------------------------------
 304    -- Scatter/gather vector handling --
 305    ------------------------------------
 306 
 307    type Msghdr is record
 308       Msg_Name       : System.Address;
 309       Msg_Namelen    : C.unsigned;
 310       Msg_Iov        : System.Address;
 311       Msg_Iovlen     : SOSC.Msg_Iovlen_T;
 312       Msg_Control    : System.Address;
 313       Msg_Controllen : C.size_t;
 314       Msg_Flags      : C.int;
 315    end record;
 316    pragma Convention (C, Msghdr);
 317 
 318    ----------------------------
 319    -- Socket sets management --
 320    ----------------------------
 321 
 322    procedure Get_Socket_From_Set
 323      (Set    : access Fd_Set;
 324       Last   : access C.int;
 325       Socket : access C.int);
 326    --  Get last socket in Socket and remove it from the socket set. The
 327    --  parameter Last is a maximum value of the largest socket. This hint is
 328    --  used to avoid scanning very large socket sets. After a call to
 329    --  Get_Socket_From_Set, Last is set back to the real largest socket in the
 330    --  socket set.
 331 
 332    procedure Insert_Socket_In_Set
 333      (Set    : access Fd_Set;
 334       Socket : C.int);
 335    --  Insert socket in the socket set
 336 
 337    function  Is_Socket_In_Set
 338      (Set    : access constant Fd_Set;
 339       Socket : C.int) return C.int;
 340    --  Check whether Socket is in the socket set, return a non-zero
 341    --  value if it is, zero if it is not.
 342 
 343    procedure Last_Socket_In_Set
 344      (Set  : access Fd_Set;
 345       Last : access C.int);
 346    --  Find the largest socket in the socket set. This is needed for select().
 347    --  When Last_Socket_In_Set is called, parameter Last is a maximum value of
 348    --  the largest socket. This hint is used to avoid scanning very large
 349    --  socket sets. After the call, Last is set back to the real largest socket
 350    --  in the socket set.
 351 
 352    procedure Remove_Socket_From_Set (Set : access Fd_Set; Socket : C.int);
 353    --  Remove socket from the socket set
 354 
 355    procedure Reset_Socket_Set (Set : access Fd_Set);
 356    --  Make Set empty
 357 
 358    ------------------------------------------
 359    -- Pairs of signalling file descriptors --
 360    ------------------------------------------
 361 
 362    type Two_Ints is array (0 .. 1) of C.int;
 363    pragma Convention (C, Two_Ints);
 364    --  Container for two int values
 365 
 366    subtype Fd_Pair is Two_Ints;
 367    --  Two_Ints as used for Create_Signalling_Fds: a pair of connected file
 368    --  descriptors, one of which (the "read end" of the connection) being used
 369    --  for reading, the other one (the "write end") being used for writing.
 370 
 371    Read_End  : constant := 0;
 372    Write_End : constant := 1;
 373    --  Indexes into an Fd_Pair value providing access to each of the connected
 374    --  file descriptors.
 375 
 376    function Inet_Pton
 377      (Af  : C.int;
 378       Cp  : System.Address;
 379       Inp : System.Address) return C.int;
 380 
 381    function C_Ioctl
 382      (Fd  : C.int;
 383       Req : SOSC.IOCTL_Req_T;
 384       Arg : access C.int) return C.int;
 385 
 386 private
 387    pragma Import (C, Get_Socket_From_Set, "__gnat_get_socket_from_set");
 388    pragma Import (C, Is_Socket_In_Set, "__gnat_is_socket_in_set");
 389    pragma Import (C, Last_Socket_In_Set, "__gnat_last_socket_in_set");
 390    pragma Import (C, Insert_Socket_In_Set, "__gnat_insert_socket_in_set");
 391    pragma Import (C, Remove_Socket_From_Set, "__gnat_remove_socket_from_set");
 392    pragma Import (C, Reset_Socket_Set, "__gnat_reset_socket_set");
 393    pragma Import (C, C_Ioctl, "__gnat_socket_ioctl");
 394    pragma Import (C, Inet_Pton, SOSC.Inet_Pton_Linkname);
 395 
 396    pragma Import (C, C_Gethostbyname, "__gnat_gethostbyname");
 397    pragma Import (C, C_Gethostbyaddr, "__gnat_gethostbyaddr");
 398    pragma Import (C, C_Getservbyname, "__gnat_getservbyname");
 399    pragma Import (C, C_Getservbyport, "__gnat_getservbyport");
 400 
 401    pragma Import (C, Servent_S_Name,  "__gnat_servent_s_name");
 402    pragma Import (C, Servent_S_Alias, "__gnat_servent_s_alias");
 403    pragma Import (C, Servent_S_Port,  "__gnat_servent_s_port");
 404    pragma Import (C, Servent_S_Proto, "__gnat_servent_s_proto");
 405 
 406    pragma Import (C, Hostent_H_Name,     "__gnat_hostent_h_name");
 407    pragma Import (C, Hostent_H_Alias,    "__gnat_hostent_h_alias");
 408    pragma Import (C, Hostent_H_Addrtype, "__gnat_hostent_h_addrtype");
 409    pragma Import (C, Hostent_H_Length,   "__gnat_hostent_h_length");
 410    pragma Import (C, Hostent_H_Addr,     "__gnat_hostent_h_addr");
 411 
 412 end GNAT.Sockets.Thin_Common;