1% ---------------------------------------------------------------------- 2% BEGIN LICENSE BLOCK 3% Version: CMPL 1.1 4% 5% The contents of this file are subject to the Cisco-style Mozilla Public 6% License Version 1.1 (the "License"); you may not use this file except 7% in compliance with the License. You may obtain a copy of the License 8% at www.eclipse-clp.org/license. 9% 10% Software distributed under the License is distributed on an "AS IS" 11% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 12% the License for the specific language governing rights and limitations 13% under the License. 14% 15% The Original Code is The ECLiPSe Constraint Logic Programming System. 16% The Initial Developer of the Original Code is Cisco Systems, Inc. 17% Portions created by the Initial Developer are 18% Copyright (C) 1998-2006 Cisco Systems, Inc. All Rights Reserved. 19% 20% Contributor(s): IC-Parc, Imperal College London 21% 22% END LICENSE BLOCK 23% 24% System: ECLiPSe Constraint Logic Programming System 25% Version: $Id: sockets.pl,v 1.3 2009/12/22 02:44:23 jschimpf Exp $ 26% ---------------------------------------------------------------------- 27 28/* 29 * IDENTIFICATION: sockets.pl 30 * 31 * DESCRIPTION: SICStus Prolog compatibility package 32 * 33 * 34 * CONTENTS: 35 * 36 * AUTHOR: Kish Shen 37 * 38 * DATE: 24 Sept. 1998 39 */ 40 41:- module(sockets). 42 43:- comment(categories, ["Compatibility"]). 44:- comment(summary, "Sicstus compatible sockets interface"). 45:- comment(author, "Kish Shen, ECRC Munich"). 46:- comment(copyright, "Cisco Systems, Inc"). 47:- comment(date, "$Date: 2009/12/22 02:44:23 $"). 48:- comment(desc, html(" 49 Note that ECLiPSe provides its own built-in socket manipulation 50 predicates which provides similar functionality to this library. 51 <P> 52 This library is only provided for compatibility with the socket 53 manipulation predicates of SICStus Prolog. To use these predicates, 54 the sockets library has to be loaded: 55 <PRE> 56 :- use_module(library(sockets)). 57 </PRE> 58 For SICStus 3.0, the sockets predicates are also in a sockets library, 59 so no changes are needed to load the library. However, for older 60 versions of SICStus, the predicates are available as built-ins, and no 61 library has to be loaded. So if the code is written for older 62 versions of SICStus, then the above line has to be added. 63 <P> 64 The sockets library can be used independently of the sicstus library. 65 ")). 66:- comment(socket/2, [template:"socket(+Domain, -Socket)", 67 summary:"Create a socket", 68 see_also:[socket/3]]). 69:- comment(socket_bind/2, [template:"socket_bind(+Socket, +Address)", 70 summary:"Bind a socket to an address", 71 see_also:[bind/2]]). 72:- comment(socket_connect/3, [template:"socket_connect(+Socket, +Address, -Stream)", 73 summary:"Connect a socket to an address", 74 see_also:[connect/2]]). 75:- comment(socket_listen/2, [template:"socket_listen(+Socket, +Length)", 76 summary:"Limit the maximum of pending connections", 77 see_also:[listen/2]]). 78:- comment(socket_accept/2, [template:"socket_accept(+Socket, -Stream)", 79 summary:"Extract the first connection to socket", 80 see_also:[accept/3]]). 81:- comment(socket_select/5, [template:"socket_select(+Socket, -NewStream, +TimeOut0, +Streams, -ReadStreams)", 82 summary:"Wait for new connection on Socket, and for data on Streams", 83 see_also:[stream_select/3]]). 84:- comment(current_host/1, [template:"current_host(?HostName)", 85 summary:"Get the host machine name", 86 see_also:[get_flag/2]]). 87 88:- export 89 socket/2, 90 socket_bind/2, 91 socket_connect/3, 92 socket_listen/2, 93 socket_accept/2, 94 socket_select/5, 95 current_host/1, 96 stream_select/3. 97 98:- comment(stream_select/3, [template:"stream_select(+Streams, +TimeOut0, -ReadStreams)", 99 summary:"Wait for data on Streams", 100 see_also:[eclipse_language:stream_select/3,select/3]]). 101 102 103 104socket(Domain, Socket) :- 105 (Domain == 'AF_INET' -> Dom = internet ; 106 Domain == 'AF_UNIX' -> Dom = unix ; error(5, socket(Domain,Socket)) 107 ), 108 sepia_kernel:socket(Dom, stream, Socket). 109 110socket_bind(Socket, Address) :- 111 translate_address(Address, Name, socket_bind(Socket,Address)), 112 sepia_kernel:bind(Socket, Name). 113 114socket_connect(Socket, Address, Stream) :- 115 translate_address(Address, Name, socket_connect(Socket,Address,Stream)), 116 Socket = Stream, 117 sepia_kernel:connect(Socket, Name). 118 119socket_listen(Socket, Length) :- 120 sepia_kernel:listen(Socket, Length). 121 122socket_accept(Socket, Stream) :- 123 sepia_kernel: accept(Socket, _, Stream). 124 125socket_select(Socket, NewStream, TimeOut0, Streams, ReadStreams) :- 126 translate_timeout(TimeOut0, TimeOut, socket_select(Socket,NewStream,TimeOut0,Streams,ReadStreams)), 127 sepia_kernel: stream_select([Socket|Streams], TimeOut, ReadStreams0), 128 (delete(Socket, ReadStreams0, ReadStreams) -> 129 sepia_kernel: accept(Socket, _, NewStream) ; ReadStreams = ReadStreams0 130 ). 131 132stream_select(Streams, TimeOut0, ReadStreams) :- 133 translate_timeout(TimeOut0, TimeOut, stream_select(Streams,TimeOut0,ReadStreams)), 134 sepia_kernel:stream_select(Streams, TimeOut, ReadStreams). 135 136current_host(HostName) :- 137 get_flag(hostname, Shostname), 138 atom_string(HostName, Shostname). 139 140 141translate_timeout(S:MS, TimeOut, _Culprit) ?- 142 integer(S), 143 integer(MS), 144 S > 0, MS > 0, !, 145 TimeOut is S + MS/1000000. 146translate_timeout(off, TimeOut, _) ?- !, 147 TimeOut = block. 148translate_timeout(_, _, Culprit) :- 149 error(5,Culprit). 150 151translate_address('AF_UNIX'(Name0), Name, _Culprit) ?- 152 atom(Name0), !, Name = Name0. 153translate_address('AF_INET'(Host,Port), Name, Culprit) ?- 154 (Culprit = socket_bind(_,_) -> true ; 155 /* assume to be socket_connect */ 156 nonvar(Host), nonvar(Port) 157 ), 158 !, Name = Host/Port. 159translate_address(_, _, Culprit) :- 160 error(5, Culprit). 161 162 163 164 165