32
33:- module(sicstus4_sockets,
34 [ socket_client_open/3,
35 socket_server_open/2,
36 socket_server_open/3,
37 socket_server_accept/4,
38 socket_server_close/1,
39 socket_select/7,
40 current_host/1
41 ]). 42
43:- reexport('../sicstus/sockets',
44 [ current_host/1
45 ]). 46
47:- use_module(library(lists)). 48:- use_module(library(socket), [tcp_connect/3]). 49
50:- multifile sicstus4:rename_module/2. 51
52sicstus4:rename_module(sockets, sicstus4_sockets).
63sicstus_address_to_swi(Address, Address) :- var(Address), !.
64sicstus_address_to_swi(inet(Nodename, Servname), SwiAddress) :- !,
65 sicstus_address_to_swi(Nodename:Servname, SwiAddress).
66sicstus_address_to_swi('':Servname, Servname) :- !.
67sicstus_address_to_swi(Address, Address).
68
72sicstus_parse_stream_options(Options, [type(Type), encoding(Encoding)]) :-
73 ( selectchk(type(Type), Options, Options1)
74 -> true
75 ; Type = text,
76 Options1 = Options
77 ),
78 ( selectchk(encoding(Encoding), Options1, Options2)
79 -> true
80 ; Encoding = iso_latin_1,
81 Options2 = Options1
82 ),
83 84 Options2 == [].
85
86sicstus_apply_stream_options(Stream, ParsedOptions) :-
87 maplist(set_stream(Stream), ParsedOptions).
88
89socket_client_open(Addr, Stream, Options) :-
90 sicstus_address_to_swi(Addr, SwiAddr),
91 sicstus_parse_stream_options(Options, ParsedOptions),
92 tcp_connect(SwiAddr, Stream, []),
93 sicstus_apply_stream_options(Stream, ParsedOptions).
94
95sicstus_address_handle_loopback(Address, false, Address) :- !.
96sicstus_address_handle_loopback(Servname, true, localhost:Servname) :- var(Servname), !.
97sicstus_address_handle_loopback(_Nodename:Servname, true, localhost:Servname) :- !.
98sicstus_address_handle_loopback(Servname, true, localhost:Servname) :- !.
99
100sicstus_server_address_to_swi(Address, Loopback, SwiAddress) :-
101 sicstus_address_to_swi(Address, TempAddress),
102 sicstus_address_handle_loopback(TempAddress, Loopback, SwiAddress).
103
107socket_server_open(Addr, ServerSocket) :- socket_server_open(Addr, ServerSocket, []).
108socket_server_open(Addr, ServerSocket, Options) :-
109 ( selectchk(reuseaddr(ReuseAddr), Options, Options1)
110 -> (ReuseAddr == true ; ReuseAddr == false)
111 ; ReuseAddr = false,
112 Options1 = Options
113 ),
114 ( selectchk(loopback(Loopback), Options1, Options2)
115 -> (Loopback == true ; Loopback == false)
116 ; Loopback = false,
117 Options2 = Options1
118 ),
119 sicstus_server_address_to_swi(Addr, Loopback, SwiAddr),
120 121 Options2 == [],
122 tcp_socket(SocketId),
123 ( ReuseAddr == true
124 -> tcp_setopt(SocketId, reuseaddr)
125 ; true
126 ),
127 tcp_bind(SocketId, SwiAddr),
128 tcp_listen(SocketId, 5),
129 tcp_open_socket(SocketId, ServerSocket).
130
131socket_server_accept(ServerSocket, Client, Stream, StreamOptions) :-
132 sicstus_parse_stream_options(StreamOptions, ParsedStreamOptions),
133 tcp_accept(ServerSocket, ClientSocket, Client),
134 tcp_open_socket(ClientSocket, Stream),
135 sicstus_apply_stream_options(Stream, ParsedStreamOptions).
136
137socket_server_close(ServerSocket) :- close(ServerSocket).
138
139sicstus_timeout_to_swi(off, infinite).
140sicstus_timeout_to_swi(Seconds:Microseconds, N) :-
141 number(Seconds),
142 number(Microseconds),
143 N is Seconds + Microseconds / 1000000,
144 N > 0.
145sicstus_timeout_to_swi(N, N) :-
146 number(N),
147 N > 0.
148
149:- use_module(library(lists), [list_to_set/2, intersection/3]). 157socket_select(ServerSockets, SReady, ReadStreams, RReady, WriteStreams, WReady, Timeout) :-
158 sicstus_timeout_to_swi(Timeout, SwiTimeout),
159 append([ServerSockets, ReadStreams, WriteStreams], AllStreamsDup),
160 list_to_set(AllStreamsDup, AllStreams),
161 wait_for_input(AllStreams, ReadyList, SwiTimeout),
162 intersection(ServerSockets, ReadyList, SReady),
163 intersection(ReadStreams, ReadyList, RReady),
164 intersection(WriteStreams, ReadyList, WReady)
SICStus 4-compatible
library(sockets)
.