summaryrefslogtreecommitdiff
path: root/gcc/ada/g-socket.ads
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/g-socket.ads')
-rw-r--r--gcc/ada/g-socket.ads891
1 files changed, 891 insertions, 0 deletions
diff --git a/gcc/ada/g-socket.ads b/gcc/ada/g-socket.ads
new file mode 100644
index 00000000000..e43ce857e99
--- /dev/null
+++ b/gcc/ada/g-socket.ads
@@ -0,0 +1,891 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT COMPILER COMPONENTS --
+-- --
+-- G N A T . S O C K E T S --
+-- --
+-- S p e c --
+-- --
+-- $Revision: 1.22 $
+-- --
+-- Copyright (C) 2001 Ada Core Technologies, Inc. --
+-- --
+-- 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 2, 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. See the GNU General Public License --
+-- for more details. You should have received a copy of the GNU General --
+-- Public License distributed with GNAT; see file COPYING. If not, write --
+-- to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, --
+-- MA 02111-1307, USA. --
+-- --
+-- As a special exception, if other files instantiate generics from this --
+-- unit, or you link this unit with other files to produce an executable, --
+-- this unit does not by itself cause the resulting executable to be --
+-- covered by the GNU General Public License. This exception does not --
+-- however invalidate any other reasons why the executable file might be --
+-- covered by the GNU Public License. --
+-- --
+-- GNAT is maintained by Ada Core Technologies Inc (http://www.gnat.com). --
+-- --
+------------------------------------------------------------------------------
+
+-- This package provides an interface to the sockets communication facility
+-- provided on many operating systems. Currently this is implemented on all
+-- native GNAT ports except for VMS. It is not yet implemented for any of
+-- the cross-ports (e.g. it is not available for VxWorks or LynxOS).
+-- Another restriction is that there is no multicast support under Windows
+-- or under any system on which the multicast support is not available or
+-- installed.
+
+with Ada.Exceptions;
+with Ada.Streams;
+
+package GNAT.Sockets is
+
+ -- Sockets are designed to provide a consistent communication
+ -- facility between applications. This package provides an
+ -- Ada-like interface similar to the one proposed as part of the
+ -- BSD socket layer. This is a system independant thick binding.
+ -- Here is a typical example of what you can do.
+
+ -- with GNAT.Sockets; use GNAT.Sockets;
+ --
+ -- with Ada.Text_IO;
+ -- with Ada.Exceptions; use Ada.Exceptions;
+ --
+ -- procedure PingPong is
+ --
+ -- Group : constant String := "239.255.128.128";
+ -- -- Multicast groupe: administratively scoped IP address
+ --
+ -- task Pong is
+ -- entry Start;
+ -- entry Stop;
+ -- end Pong;
+ --
+ -- task body Pong is
+ -- Address : Sock_Addr_Type;
+ -- Server : Socket_Type;
+ -- Socket : Socket_Type;
+ -- Channel : Stream_Access;
+ --
+ -- begin
+ -- accept Start;
+ --
+ -- -- Get an Internet address of a host (here "localhost").
+ -- -- Note that a host can have several addresses. Here we get
+ -- -- the first one which is supposed to be the official one.
+ --
+ -- Address.Addr := Addresses (Get_Host_By_Name ("localhost"), 1);
+ --
+ -- -- Get a socket address that is an Internet address and a port
+ --
+ -- Address.Port := 5432;
+ --
+ -- -- The first step is to create a socket. Once created, this
+ -- -- socket must be associated to with an address. Usually only a
+ -- -- server (Pong here) needs to bind an address explicitly.
+ -- -- Most of the time clients can skip this step because the
+ -- -- socket routines will bind an arbitrary address to an unbound
+ -- -- socket.
+ --
+ -- Create_Socket (Server);
+ --
+ -- -- Allow reuse of local addresses.
+ --
+ -- Set_Socket_Option
+ -- (Server,
+ -- Socket_Level,
+ -- (Reuse_Address, True));
+ --
+ -- Bind_Socket (Server, Address);
+ --
+ -- -- A server marks a socket as willing to receive connect events.
+ --
+ -- Listen_Socket (Server);
+ --
+ -- -- Once a server calls Listen_Socket, incoming connects events
+ -- -- can be accepted. The returned Socket is a new socket that
+ -- -- represents the server side of the connection. Server remains
+ -- -- available to receive further connections.
+ --
+ -- Accept_Socket (Server, Socket, Address);
+ --
+ -- -- Return a stream associated to the connected socket.
+ --
+ -- Channel := Stream (Socket);
+ --
+ -- -- Force Pong to block
+ --
+ -- delay 0.2;
+ --
+ -- -- Receive and print message from client Ping.
+ --
+ -- declare
+ -- Message : String := String'Input (Channel);
+ --
+ -- begin
+ -- Ada.Text_IO.Put_Line (Message);
+ --
+ -- -- Send same message to server Pong.
+ --
+ -- String'Output (Channel, Message);
+ -- end;
+ --
+ -- Close_Socket (Server);
+ -- Close_Socket (Socket);
+ --
+ -- -- Part of the multicast example
+ --
+ -- -- Create a datagram socket to send connectionless, unreliable
+ -- -- messages of a fixed maximum length.
+ --
+ -- Create_Socket (Socket, Family_Inet, Socket_Datagram);
+ --
+ -- -- Allow reuse of local addresses.
+ --
+ -- Set_Socket_Option
+ -- (Socket,
+ -- Socket_Level,
+ -- (Reuse_Address, True));
+ --
+ -- -- Join a multicast group.
+ --
+ -- Set_Socket_Option
+ -- (Socket,
+ -- IP_Protocol_For_IP_Level,
+ -- (Add_Membership, Inet_Addr (Group), Any_Inet_Addr));
+ --
+ -- -- Controls the live time of the datagram to avoid it being
+ -- -- looped forever due to routing errors. Routers decrement
+ -- -- the TTL of every datagram as it traverses from one network
+ -- -- to another and when its value reaches 0 the packet is
+ -- -- dropped. Default is 1.
+ --
+ -- Set_Socket_Option
+ -- (Socket,
+ -- IP_Protocol_For_IP_Level,
+ -- (Multicast_TTL, 1));
+ --
+ -- -- Want the data you send to be looped back to your host.
+ --
+ -- Set_Socket_Option
+ -- (Socket,
+ -- IP_Protocol_For_IP_Level,
+ -- (Multicast_Loop, True));
+ --
+ -- -- If this socket is intended to receive messages, bind it to a
+ -- -- given socket address.
+ --
+ -- Address.Addr := Any_Inet_Addr;
+ -- Address.Port := 55505;
+ --
+ -- Bind_Socket (Socket, Address);
+ --
+ -- -- If this socket is intended to send messages, provide the
+ -- -- receiver socket address.
+ --
+ -- Address.Addr := Inet_Addr (Group);
+ -- Address.Port := 55506;
+ --
+ -- Channel := Stream (Socket, Address);
+ --
+ -- -- Receive and print message from client Ping.
+ --
+ -- declare
+ -- Message : String := String'Input (Channel);
+ --
+ -- begin
+ --
+ -- -- Get the address of the sender.
+ --
+ -- Address := Get_Address (Channel);
+ -- Ada.Text_IO.Put_Line (Message & " from " & Image (Address));
+ --
+ -- -- Send same message to server Pong.
+ --
+ -- String'Output (Channel, Message);
+ -- end;
+ --
+ -- Close_Socket (Socket);
+ --
+ -- accept Stop;
+ --
+ -- exception when E : others =>
+ -- Ada.Text_IO.Put_Line
+ -- (Exception_Name (E) & ": " & Exception_Message (E));
+ -- end Pong;
+ --
+ -- task Ping is
+ -- entry Start;
+ -- entry Stop;
+ -- end Ping;
+ --
+ -- task body Ping is
+ -- Address : Sock_Addr_Type;
+ -- Socket : Socket_Type;
+ -- Channel : Stream_Access;
+ --
+ -- begin
+ -- accept Start;
+ --
+ -- -- See comments in Ping section for the first steps.
+ --
+ -- Address.Addr := Addresses (Get_Host_By_Name ("localhost"), 1);
+ -- Address.Port := 5432;
+ -- Create_Socket (Socket);
+ --
+ -- Set_Socket_Option
+ -- (Socket,
+ -- Socket_Level,
+ -- (Reuse_Address, True));
+ --
+ -- -- Force Pong to block
+ --
+ -- delay 0.2;
+ --
+ -- -- If the client's socket is not bound, Connect_Socket will
+ -- -- bind to an unused address. The client uses Connect_Socket to
+ -- -- create a logical connection between the client's socket and
+ -- -- a server's socket returned by Accept_Socket.
+ --
+ -- Connect_Socket (Socket, Address);
+ --
+ -- Channel := Stream (Socket);
+ --
+ -- -- Send message to server Pong.
+ --
+ -- String'Output (Channel, "Hello world");
+ --
+ -- -- Force Ping to block
+ --
+ -- delay 0.2;
+ --
+ -- -- Receive and print message from server Pong.
+ --
+ -- Ada.Text_IO.Put_Line (String'Input (Channel));
+ -- Close_Socket (Socket);
+ --
+ -- -- Part of multicast example. Code similar to Pong's one.
+ --
+ -- Create_Socket (Socket, Family_Inet, Socket_Datagram);
+ --
+ -- Set_Socket_Option
+ -- (Socket,
+ -- Socket_Level,
+ -- (Reuse_Address, True));
+ --
+ -- Set_Socket_Option
+ -- (Socket,
+ -- IP_Protocol_For_IP_Level,
+ -- (Add_Membership, Inet_Addr (Group), Any_Inet_Addr));
+ --
+ -- Set_Socket_Option
+ -- (Socket,
+ -- IP_Protocol_For_IP_Level,
+ -- (Multicast_TTL, 1));
+ --
+ -- Set_Socket_Option
+ -- (Socket,
+ -- IP_Protocol_For_IP_Level,
+ -- (Multicast_Loop, True));
+ --
+ -- Address.Addr := Any_Inet_Addr;
+ -- Address.Port := 55506;
+ --
+ -- Bind_Socket (Socket, Address);
+ --
+ -- Address.Addr := Inet_Addr (Group);
+ -- Address.Port := 55505;
+ --
+ -- Channel := Stream (Socket, Address);
+ --
+ -- -- Send message to server Pong.
+ --
+ -- String'Output (Channel, "Hello world");
+ --
+ -- -- Receive and print message from server Pong.
+ --
+ -- declare
+ -- Message : String := String'Input (Channel);
+ --
+ -- begin
+ -- Address := Get_Address (Channel);
+ -- Ada.Text_IO.Put_Line (Message & " from " & Image (Address));
+ -- end;
+ --
+ -- Close_Socket (Socket);
+ --
+ -- accept Stop;
+ --
+ -- exception when E : others =>
+ -- Ada.Text_IO.Put_Line
+ -- (Exception_Name (E) & ": " & Exception_Message (E));
+ -- end Ping;
+ --
+ -- begin
+ -- -- Indicate whether the thread library provides process
+ -- -- blocking IO. Basically, if you are not using FSU threads
+ -- -- the default is ok.
+ --
+ -- Initialize (Process_Blocking_IO => False);
+ -- Ping.Start;
+ -- Pong.Start;
+ -- Ping.Stop;
+ -- Pong.Stop;
+ -- Finalize;
+ -- end PingPong;
+
+ procedure Initialize (Process_Blocking_IO : Boolean := False);
+ -- Initialize must be called before using any socket routines. If
+ -- the thread library provides process blocking IO - basically
+ -- with FSU threads - GNAT.Sockets should be initialized with a
+ -- value of True to simulate thread blocking IO. Further calls to
+ -- Initialize will be ignored.
+
+ procedure Finalize;
+ -- After Finalize is called it is not possible to use any routines
+ -- exported in by this package. This procedure is idempotent.
+
+ type Socket_Type is private;
+ -- Sockets are used to implement a reliable bi-directional
+ -- point-to-point, stream-based connections between
+ -- hosts. No_Socket provides a special value to denote
+ -- uninitialized sockets.
+
+ No_Socket : constant Socket_Type;
+
+ Socket_Error : exception;
+ -- There is only one exception in this package to deal with an
+ -- error during a socket routine. Once raised, its message
+ -- contains a string describing the error code.
+
+ function Image (Socket : Socket_Type) return String;
+ -- Return a printable string for Socket
+
+ function To_C (Socket : Socket_Type) return Integer;
+ -- Return a file descriptor to be used by external subprograms
+ -- especially the C functions that are not yet interfaced in this
+ -- package.
+
+ type Family_Type is (Family_Inet, Family_Inet6);
+ -- Address family (or protocol family) identifies the
+ -- communication domain and groups protocols with similar address
+ -- formats. IPv6 will soon be supported.
+
+ type Mode_Type is (Socket_Stream, Socket_Datagram);
+ -- Stream sockets provide connection-oriented byte
+ -- streams. Datagram sockets support unreliable connectionless
+ -- message based communication.
+
+ type Shutmode_Type is (Shut_Read, Shut_Write, Shut_Read_Write);
+ -- When a process closes a socket, the policy is to retain any
+ -- data queued until either a delivery or a timeout expiration (in
+ -- this case, the data are discarded). A finer control is
+ -- available through shutdown. With Shut_Read, no more data can be
+ -- received from the socket. With_Write, no more data can be
+ -- transmitted. Neither transmission nor reception can be
+ -- performed with Shut_Read_Write.
+
+ type Port_Type is new Natural;
+ -- Classical port definition. No_Port provides a special value to
+ -- denote uninitialized port. Any_Port provides a special value
+ -- enabling all ports.
+
+ Any_Port : constant Port_Type;
+ No_Port : constant Port_Type;
+
+ type Inet_Addr_Type (Family : Family_Type := Family_Inet) is private;
+ -- An Internet address depends on an address family (IPv4 contains
+ -- 4 octets and Ipv6 contains 16 octets). Any_Inet_Address is a
+ -- special value treated like a wildcard enabling all addresses.
+ -- No_Inet_Addr provides a special value to denote uninitialized
+ -- inet addresses.
+
+ Any_Inet_Addr : constant Inet_Addr_Type;
+ No_Inet_Addr : constant Inet_Addr_Type;
+
+ type Sock_Addr_Type (Family : Family_Type := Family_Inet) is record
+ Addr : Inet_Addr_Type (Family);
+ Port : Port_Type;
+ end record;
+ -- Socket addresses fully define a socket connection with a
+ -- protocol family, an Internet address and a port. No_Sock_Addr
+ -- provides a special value for uninitialized socket addresses.
+
+ No_Sock_Addr : constant Sock_Addr_Type;
+
+ function Image (Value : Inet_Addr_Type) return String;
+ -- Return an image of an Internet address. IPv4 notation consists
+ -- in 4 octets in decimal format separated by dots. IPv6 notation
+ -- consists in 16 octets in hexadecimal format separated by
+ -- colons (and possibly dots).
+
+ function Image (Value : Sock_Addr_Type) return String;
+ -- Return inet address image and port image separated by a colon.
+
+ function Inet_Addr (Image : String) return Inet_Addr_Type;
+ -- Convert address image from numbers-and-dots notation into an
+ -- inet address.
+
+ -- Host entries provide a complete information on a given host:
+ -- the official name, an array of alternative names or aliases and
+ -- array of network addresses.
+
+ type Host_Entry_Type
+ (Aliases_Length, Addresses_Length : Natural) is private;
+
+ function Official_Name (E : Host_Entry_Type) return String;
+ -- Return official name in host entry
+
+ function Aliases_Length (E : Host_Entry_Type) return Natural;
+ -- Return number of aliases in host entry
+
+ function Addresses_Length (E : Host_Entry_Type) return Natural;
+ -- Return number of addresses in host entry
+
+ function Aliases
+ (E : Host_Entry_Type;
+ N : Positive := 1)
+ return String;
+ -- Return N'th aliases in host entry. The first index is 1.
+
+ function Addresses
+ (E : Host_Entry_Type;
+ N : Positive := 1)
+ return Inet_Addr_Type;
+ -- Return N'th addresses in host entry. The first index is 1.
+
+ Host_Error : exception;
+ -- Exception raised by the two following procedures. Once raised,
+ -- its message contains a string describing the error code. This
+ -- exception is raised when an host entry can not be retrieved.
+
+ function Get_Host_By_Address
+ (Address : Inet_Addr_Type;
+ Family : Family_Type := Family_Inet)
+ return Host_Entry_Type;
+ -- Return host entry structure for the given inet address
+
+ function Get_Host_By_Name
+ (Name : String)
+ return Host_Entry_Type;
+ -- Return host entry structure for the given host name
+
+ function Host_Name return String;
+ -- Return the name of the current host
+
+ -- Errors are described by an enumeration type. There is only one
+ -- exception Socket_Error in this package to deal with an error
+ -- during a socket routine. Once raised, its message contains the
+ -- error code between brackets and a string describing the error
+ -- code.
+
+ type Error_Type is
+ (Permission_Denied,
+ Address_Already_In_Use,
+ Cannot_Assign_Requested_Address,
+ Address_Family_Not_Supported_By_Protocol,
+ Operation_Already_In_Progress,
+ Bad_File_Descriptor,
+ Connection_Refused,
+ Bad_Address,
+ Operation_Now_In_Progress,
+ Interrupted_System_Call,
+ Invalid_Argument,
+ Input_Output_Error,
+ Transport_Endpoint_Already_Connected,
+ Message_Too_Long,
+ Network_Is_Unreachable,
+ No_Buffer_Space_Available,
+ Protocol_Not_Available,
+ Transport_Endpoint_Not_Connected,
+ Operation_Not_Supported,
+ Protocol_Not_Supported,
+ Socket_Type_Not_Supported,
+ Connection_Timed_Out,
+ Resource_Temporarily_Unavailable,
+ Unknown_Host,
+ Host_Name_Lookup_Failure,
+ No_Address_Associated_With_Name,
+ Unknown_Server_Error,
+ Cannot_Resolve_Error);
+
+ -- Get_Socket_Options and Set_Socket_Options manipulate options
+ -- associated with a socket. Options may exist at multiple
+ -- protocol levels in the communication stack. Socket_Level is the
+ -- uppermost socket level.
+
+ type Level_Type is (
+ Socket_Level,
+ IP_Protocol_For_IP_Level,
+ IP_Protocol_For_UDP_Level,
+ IP_Protocol_For_TCP_Level);
+
+ -- There are several options available to manipulate sockets. Each
+ -- option has a name and several values available. Most of the
+ -- time, the value is a boolean to enable or disable this option.
+
+ type Option_Name is (
+ Keep_Alive, -- Enable sending of keep-alive messages
+ Reuse_Address, -- Allow bind to reuse local address
+ Broadcast, -- Enable datagram sockets to recv/send broadcast packets
+ Send_Buffer, -- Set/get the maximum socket send buffer in bytes
+ Receive_Buffer, -- Set/get the maximum socket recv buffer in bytes
+ Linger, -- Shutdown wait for msg to be sent or timeout occur
+ Error, -- Get and clear the pending socket error
+ No_Delay, -- Do not delay send to coalesce packets (TCP_NODELAY)
+ Add_Membership, -- Join a multicast group
+ Drop_Membership, -- Leave a multicast group
+ Multicast_TTL, -- Indicates the time-to-live of sent multicast packets
+ Multicast_Loop); -- Sent multicast packets are looped to the local socket
+
+ type Option_Type (Name : Option_Name := Keep_Alive) is record
+ case Name is
+ when Keep_Alive |
+ Reuse_Address |
+ Broadcast |
+ Linger |
+ No_Delay |
+ Multicast_Loop =>
+ Enabled : Boolean;
+
+ case Name is
+ when Linger =>
+ Seconds : Natural;
+ when others =>
+ null;
+ end case;
+
+ when Send_Buffer |
+ Receive_Buffer =>
+ Size : Natural;
+
+ when Error =>
+ Error : Error_Type;
+
+ when Add_Membership |
+ Drop_Membership =>
+ Multiaddr : Inet_Addr_Type;
+ Interface : Inet_Addr_Type;
+
+ when Multicast_TTL =>
+ Time_To_Live : Natural;
+
+ end case;
+ end record;
+
+ -- There are several controls available to manipulate
+ -- sockets. Each option has a name and several values available.
+ -- These controls differ from the socket options in that they are
+ -- not specific to sockets but are available for any device.
+
+ type Request_Name is (
+ Non_Blocking_IO, -- Cause a caller not to wait on blocking operations.
+ N_Bytes_To_Read); -- Return the number of bytes available to read
+
+ type Request_Type (Name : Request_Name := Non_Blocking_IO) is record
+ case Name is
+ when Non_Blocking_IO =>
+ Enabled : Boolean;
+
+ when N_Bytes_To_Read =>
+ Size : Natural;
+
+ end case;
+ end record;
+
+ procedure Create_Socket
+ (Socket : out Socket_Type;
+ Family : Family_Type := Family_Inet;
+ Mode : Mode_Type := Socket_Stream);
+ -- Create an endpoint for communication. Raise Socket_Error on error.
+
+ procedure Accept_Socket
+ (Server : Socket_Type;
+ Socket : out Socket_Type;
+ Address : out Sock_Addr_Type);
+ -- Extract the first connection request on the queue of pending
+ -- connections, creates a new connected socket with mostly the
+ -- same properties as Server, and allocates a new socket. The
+ -- returned Address is filled in with the address of the
+ -- connection. Raise Socket_Error on error.
+
+ procedure Bind_Socket
+ (Socket : Socket_Type;
+ Address : Sock_Addr_Type);
+ -- Once a socket is created, assign a local address to it. Raise
+ -- Socket_Error on error.
+
+ procedure Close_Socket (Socket : Socket_Type);
+ -- Close a socket and more specifically a non-connected socket.
+ -- Fail silently.
+
+ procedure Connect_Socket
+ (Socket : Socket_Type;
+ Server : in out Sock_Addr_Type);
+ -- Make a connection to another socket which has the address of
+ -- Server. Raise Socket_Error on error.
+
+ procedure Control_Socket
+ (Socket : Socket_Type;
+ Request : in out Request_Type);
+ -- Obtain or set parameter values that control the socket. This
+ -- control differs from the socket options in that they are not
+ -- specific to sockets but are avaiable for any device.
+
+ function Get_Peer_Name (Socket : Socket_Type) return Sock_Addr_Type;
+ -- Return the peer or remote socket address of a socket. Raise
+ -- Socket_Error on error.
+
+ function Get_Socket_Name (Socket : Socket_Type) return Sock_Addr_Type;
+ -- Return the local or current socket address of a socket. Raise
+ -- Socket_Error on error.
+
+ function Get_Socket_Option
+ (Socket : Socket_Type;
+ Level : Level_Type := Socket_Level;
+ Name : Option_Name)
+ return Option_Type;
+ -- Get the options associated with a socket. Raise Socket_Error on
+ -- error.
+
+ procedure Listen_Socket
+ (Socket : Socket_Type;
+ Length : Positive := 15);
+ -- To accept connections, a socket is first created with
+ -- Create_Socket, a willingness to accept incoming connections and
+ -- a queue Length for incoming connections are specified. Raise
+ -- Socket_Error on error.
+
+ procedure Receive_Socket
+ (Socket : Socket_Type;
+ Item : out Ada.Streams.Stream_Element_Array;
+ Last : out Ada.Streams.Stream_Element_Offset);
+ -- Receive message from Socket. Last is the index value such that
+ -- Item (Last) is the last character assigned. Note that Last is
+ -- set to Item'First - 1 when the socket has been closed by
+ -- peer. This is not an error and no exception is raised. Raise
+ -- Socket_Error on error.
+
+ 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);
+ -- Receive message from Socket. If Socket is not
+ -- connection-oriented, the source address From of the message is
+ -- filled in. Last is the index value such that Item (Last) is the
+ -- last character assigned. Raise Socket_Error on error.
+
+ function Resolve_Exception
+ (Occurrence : Ada.Exceptions.Exception_Occurrence)
+ return Error_Type;
+ -- When Socket_Error or Host_Error are raised, the exception
+ -- message contains the error code between brackets and a string
+ -- describing the error code. Resolve_Error extracts the error
+ -- code from an exception message and translate it into an
+ -- enumeration value.
+
+ procedure Send_Socket
+ (Socket : Socket_Type;
+ Item : Ada.Streams.Stream_Element_Array;
+ Last : out Ada.Streams.Stream_Element_Offset);
+ -- Transmit a message to another socket. Note that Last is set to
+ -- Item'First when socket has been closed by peer. This is not an
+ -- error and no exception is raised. Raise Socket_Error on error;
+
+ procedure Send_Socket
+ (Socket : Socket_Type;
+ Item : Ada.Streams.Stream_Element_Array;
+ Last : out Ada.Streams.Stream_Element_Offset;
+ To : Sock_Addr_Type);
+ -- Transmit a message to another socket. The address is given by
+ -- To. Raise Socket_Error on error;
+
+ procedure Set_Socket_Option
+ (Socket : Socket_Type;
+ Level : Level_Type := Socket_Level;
+ Option : Option_Type);
+ -- Manipulate socket options. Raise Socket_Error on error.
+
+ procedure Shutdown_Socket
+ (Socket : Socket_Type;
+ How : Shutmode_Type := Shut_Read_Write);
+ -- Shutdown a connected socket. If How is Shut_Read, further
+ -- receives will be disallowed. If How is Shut_Write, further
+ -- sends will be disallowed. If how is Shut_Read_Write, further
+ -- sends and receives will be disallowed. Fail silently.
+
+ type Stream_Access is access all Ada.Streams.Root_Stream_Type'Class;
+ -- Same interface as Ada.Streams.Stream_IO
+
+ function Stream
+ (Socket : Socket_Type)
+ return Stream_Access;
+ -- Associate a stream with a stream-based socket that is already
+ -- connected.
+
+ function Stream
+ (Socket : Socket_Type;
+ Send_To : Sock_Addr_Type)
+ return Stream_Access;
+ -- Associate a stream with a datagram-based socket that is already
+ -- bound. Send_To is the socket address to which messages are
+ -- being sent.
+
+ function Get_Address
+ (Stream : Stream_Access)
+ return Sock_Addr_Type;
+ -- Return the socket address from which the last message was
+ -- received.
+
+ type Socket_Set_Type is private;
+ -- This type allows to manipulate sets of sockets. It allows to
+ -- wait for events on multiple endpoints at one time. This is an
+ -- access type on a system dependent structure. To avoid memory
+ -- leaks it is highly recommended to clean the access value with
+ -- procedure Empty.
+
+ procedure Clear (Item : in out Socket_Set_Type; Socket : Socket_Type);
+ -- Remove Socket from Item
+
+ procedure Set (Item : in out Socket_Set_Type; Socket : Socket_Type);
+ -- Insert Socket into Item
+
+ procedure Empty (Item : in out Socket_Set_Type);
+ -- Remove all Sockets from Item and deallocate internal data
+
+ function Is_Empty
+ (Item : Socket_Set_Type)
+ return Boolean;
+ -- Return True if Item is empty
+
+ function Is_Set
+ (Item : Socket_Set_Type;
+ Socket : Socket_Type)
+ return Boolean;
+ -- Return True if Socket is present in Item
+
+ -- C select() waits for a number of file descriptors to change
+ -- status. Usually, three independant sets of descriptors are
+ -- watched (read, write and exception). A timeout gives an upper
+ -- bound on the amount of time elapsed before select returns.
+ -- This function blocks until an event occurs. On some platforms,
+ -- C select can block the full process.
+ --
+ -- Check_Selector provides the very same behaviour. The only
+ -- difference is that it does not watch for exception events. Note
+ -- that on some platforms it is kept process blocking in purpose.
+ -- The timeout parameter allows the user to have the behaviour he
+ -- wants. Abort_Selector allows to abort safely a Check_Selector
+ -- that is blocked forever. A special file descriptor is opened by
+ -- Create_Selector and included in each call to
+ -- Check_Selector. Abort_Selector causes an event to occur on this
+ -- descriptor in order to unblock Check_Selector. The user must
+ -- call Close_Selector to discard this special file. A reason to
+ -- abort a select operation is typically to add a socket in one of
+ -- the socket sets when the timeout is set to forever.
+
+ Forever : constant Duration;
+
+ type Selector_Type is limited private;
+ type Selector_Access is access all Selector_Type;
+
+ procedure Create_Selector (Selector : out Selector_Type);
+ -- Create a new selector
+
+ procedure Close_Selector (Selector : in out Selector_Type);
+ -- Close Selector and all internal descriptors associated
+
+ type Selector_Status is (Completed, Expired, Aborted);
+
+ procedure Check_Selector
+ (Selector : in out Selector_Type;
+ R_Socket_Set : in out Socket_Set_Type;
+ W_Socket_Set : in out Socket_Set_Type;
+ Status : out Selector_Status;
+ Timeout : Duration := Forever);
+ -- Return when one Socket in R_Socket_Set has some data to be read
+ -- or if one Socket in W_Socket_Set is ready to receive some
+ -- data. In these cases Status is set to Completed and sockets
+ -- that are ready are set in R_Socket_Set or W_Socket_Set. Status
+ -- is set to Expired if no socket was ready after a Timeout
+ -- expiration. Status is set to Aborted if an abort signal as been
+ -- received while checking socket status. As this procedure
+ -- returns when Timeout occurs, it is a design choice to keep this
+ -- procedure process blocking. Note that a Timeout of 0.0 returns
+ -- immediatly.
+
+ procedure Abort_Selector (Selector : Selector_Type);
+ -- Send an abort signal to the selector.
+
+private
+
+ type Socket_Type is new Integer;
+ No_Socket : constant Socket_Type := -1;
+
+ Forever : constant Duration := Duration'Last;
+
+ type Selector_Type is limited record
+ R_Sig_Socket : Socket_Type;
+ W_Sig_Socket : Socket_Type;
+ In_Progress : Boolean := False;
+ end record;
+ -- The two signalling sockets are used to abort a select
+ -- operation.
+
+ type Socket_Set_Record;
+ type Socket_Set_Type is access all Socket_Set_Record;
+
+ subtype Inet_Addr_Comp_Type is Natural range 0 .. 255;
+ -- Octet for Internet address
+
+ type Inet_Addr_VN_Type is array (Natural range <>) of Inet_Addr_Comp_Type;
+
+ subtype Inet_Addr_V4_Type is Inet_Addr_VN_Type (1 .. 4);
+ subtype Inet_Addr_V6_Type is Inet_Addr_VN_Type (1 .. 16);
+
+ type Inet_Addr_Type (Family : Family_Type := Family_Inet) is record
+ case Family is
+ when Family_Inet =>
+ Sin_V4 : Inet_Addr_V4_Type := (others => 0);
+
+ when Family_Inet6 =>
+ Sin_V6 : Inet_Addr_V6_Type := (others => 0);
+ end case;
+ end record;
+
+ Any_Port : constant Port_Type := 0;
+ No_Port : constant Port_Type := 0;
+
+ Any_Inet_Addr : constant Inet_Addr_Type := (Family_Inet, (others => 0));
+ No_Inet_Addr : constant Inet_Addr_Type := (Family_Inet, (others => 0));
+
+ No_Sock_Addr : constant Sock_Addr_Type := (Family_Inet, No_Inet_Addr, 0);
+
+ Max_Host_Name_Length : constant := 64;
+ -- The constant MAXHOSTNAMELEN is usually set to 64
+
+ subtype Host_Name_Index is Natural range 1 .. Max_Host_Name_Length;
+
+ type Host_Name_Type
+ (Length : Host_Name_Index := Max_Host_Name_Length)
+ is record
+ Name : String (1 .. Length);
+ end record;
+ -- We need fixed strings to avoid access types in host entry type
+
+ type Host_Name_Array is array (Natural range <>) of Host_Name_Type;
+ type Inet_Addr_Array is array (Natural range <>) of Inet_Addr_Type;
+
+ type Host_Entry_Type (Aliases_Length, Addresses_Length : Natural) is record
+ Official : Host_Name_Type;
+ Aliases : Host_Name_Array (1 .. Aliases_Length);
+ Addresses : Inet_Addr_Array (1 .. Addresses_Length);
+ end record;
+
+end GNAT.Sockets;