----------------------------------------------------------------------------- -- -- Onions Network Streams Library -- -- O N I O N S . S O C K E T S -- -- B o d y -- -- Copyright (C) 1997-1998 Regents of the University of California -- -- Onions is free software; you can redistribute it and/or modify it under -- the terms of the GNU General Public License as published by the Free -- Software Foundation, with or without the single exception listed below; -- either version 2, or (at your option) any later version. Onions is -- distributed in the hope that it will be useful, but WITHOUT 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 Onions; see the 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 -- library, or you link this library with other files to produce an -- executable, this library 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 General Public License. -- -- Portions of this unit have been derived from version 1.02 of the Garlic -- library of GLADE, the Ada95 Distributed Systems Annex for GNAT. GLADE -- is maintained by ACT Europe (see ). -- -- GLADE is Copyright (C) 1996,1997 Free Software Foundation, Inc. -- All source code that is shared by both GLADE version 1.02 and -- this unit remains under the FSF copyright. -- -- Rewritten for Onions in 1997 by Roy T. Fielding and Kari Nies ----------------------------------------------------------------------------- -- -- The Sockets package provides utility routines for connecting -- via sockets, accepting connections via sockets, and setting -- socket options. -- with System; with Interfaces.C.Strings; with Onions.Constants; with Onions.Naming; pragma Elaborate_All (Onions.Naming); with Onions.Thin; with Onions.OS; use System; use Onions.Constants; use Onions.Naming; use Onions.Thin; use Onions.OS; package body Onions.Sockets is -- This system implements Sockets communication. use type C.int; use type C.unsigned_short; -- Shortcuts. --------------------- -- Port_To_Network -- --------------------- -- Convert a port number to a network port number. -- function Port_To_Network (Port : C.unsigned_short) return C.unsigned_short is begin if System.Default_Bit_Order = System.High_Order_First then -- No conversion needed. On these platforms, htons() defaults -- to a null procedure. return Port; else -- We need to swap the high and low byte on this short to make -- the port number network compliant. return (Port / 256) + (Port mod 256) * 256; end if; end Port_To_Network; -------------------------- -- Establish_Connection -- -------------------------- -- Establish a socket to a remote location and return the file descriptor. -- function Establish_Connection (Location : Host_Location) return Descriptor is FD : Descriptor; Sin : Sockaddr_In_Access := new Sockaddr_In; Code : C.int; Errno : C.int; begin FD := C_socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); if FD = Failure then Free (Sin); OS.Raise_Error (Connection_Error'Identity, OS.C_errno, "Unable to obtain socket"); end if; Sin.Sin_Family := AF_INET; Sin.Sin_Addr := Naming.To_In_Addr (Location.Addr); Sin.Sin_Port := Port_To_Network (Location.Port); loop Code := C_connect (FD, To_Sockaddr_Access (Sin), Sin.all'Size / 8); if Code = Success then Free (Sin); return FD; end if; case OS.C_errno is when EINTR => null; when EINPROGRESS => Errno := OS.C_errno; exit when OS.Wait_For_Fd (OS.Fd_Writable, FD, 30000) = 0; when others => Errno := OS.C_errno; exit; end case; end loop; Code := C_close (FD); Free (Sin); OS.Raise_Error (Connection_Error'Identity, Errno, "Connect failed"); return Failure; -- never reached end Establish_Connection; -- Image provides a readable form of Host_Location -- function Image (Location : Host_Location) return String is begin return Image (Location.Addr) & ":" & Image (Location.Port); end Image; end Onions.Sockets;