1% BEGIN LICENSE BLOCK
2% Version: CMPL 1.1
3%
4% The contents of this file are subject to the Cisco-style Mozilla Public
5% License Version 1.1 (the "License"); you may not use this file except
6% in compliance with the License.  You may obtain a copy of the License
7% at www.eclipse-clp.org/license.
8% 
9% Software distributed under the License is distributed on an "AS IS"
10% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See
11% the License for the specific language governing rights and limitations
12% under the License. 
13% 
14% The Original Code is  The ECLiPSe Constraint Logic Programming System. 
15% The Initial Developer of the Original Code is  Cisco Systems, Inc. 
16% Portions created by the Initial Developer are
17% Copyright (C) 2006 Cisco Systems, Inc.  All Rights Reserved.
18% 
19% Contributor(s): 
20% 
21% END LICENSE BLOCK
22
23:- comment(alias, "Stream I/O").
24:- comment(summary, "Built-ins to open, manipulate and close I/O streams").
25:- comment(categories, ["Built-In Predicates"]).
26
27:- comment(open / 4, [
28        summary:"Opens the I/O source or sink SourceSink in mode Mode and associates it
29with the stream identifier Stream.
30
31",
32        amode:(open(++,+,-,++) is det),
33        amode:(open(++,+,+,++) is det),
34        desc:html("   This predicate opens an ECLiPSe I/O stream.
35
36<P>
37   The most common use is for opening files. In this case, SourceSink
38   is a file name (atom or string).
39
40<P>
41   Mode is one of the following
42
43<P>
44<PRE>
45    read         open for reading
46    write        open for writing
47    update       open for reading and writing
48    append       open for writing at the end
49</PRE>
50   A file must already exist if it is to be opened in read mode.  A file
51   opened in append mode is opened in write mode at the end of the file.
52   If an existing file is opened in write mode, it is truncated to zero
53   size, i.e. its previous content is lost.
54
55<P>
56   If Stream is a variable, it will be instantiated to a system-generated
57   stream handle.  This handle can subsequently be used to identify the
58   stream.  If Stream is an atom, then this atom will be used as a symbolic
59   alias name for the stream (like with the alias(Name) option, or
60   set_stream/2).  The use of handles should be preferred.
61
62<P>
63   If SourceSink is of the form string(InitialString), then a so-called
64   string stream is opened.  A string stream is basically an in-memory
65   file and its initial contents is the string InitialString.
66   A string stream can be used like any other stream, i.e. it is possible
67   to read, write and seek like on a true file.
68   The current contents of a string stream can at any time be retrieved
69   as a whole using get_stream_info(Stream, name, Contents).
70
71<P>
72   If SourceSink is of the form queue(InitialString), then a queue
73   stream is opened. It behaves like a string that can be written at the
74   end and read from the beginning.  Seeking is not allowed on queues.
75   The current contents of a queue can at any time be retrieved as a
76   whole using get_stream_info(Stream, name, Contents). Queues are
77   considered to be at end-of-file while they are empty. 
78   Queues can be configured to raise an event every time something
79   is written to the previously empty queue (see open/4).
80
81<P>
82   If SourceSink is of the form fd(Integer), then the stream in opened
83   onto an existing operating system file descriptor.
84
85<P>
86   Options is a list of zero or more of the following stream options:
87<DL>
88<DT><STRONG>alias(Name)</STRONG><DD>
89    Make the stream known under an alternative name.  Name is an atom,
90    and must not already be a stream alias. See also set_stream/2.
91
92<DT><STRONG>compress(OnOff)</STRONG><DD>
93    a hint for output operations (e.g. write_exdr/2) to use a more
94    compact output format (output streams only). OnOff is one of the
95    atoms on or off. The default is on (for files, pipes and sockets)
96    or off (for queues and string streams).
97
98<DT><STRONG>delete_file(When)</STRONG><DD>
99    This option applies to file streams only: the value 'when_closed'
100    causes the associated file to be deleted as soon as the stream is closed
101    (whether implicitly or explicitly).  The value 'when_lost' causes
102    the associated file to be deleted only when the stream is implicitly
103    closed, either because of failure across the opening, or because
104    its handles were garbage collected.  The default is 'off'.
105
106<DT><STRONG>encoding(Code)</STRONG><DD>
107    The character encoding used on the stream.  In version 6.1, the
108    only allowed values are: octet, ascii, and iso_latin_1 (the default).
109
110<DT><STRONG>end_of_line(CrLf)</STRONG><DD>
111    This option affects only write-streams and determines which
112    end-of-line character sequence is written by predicates like nl/1,
113    writeln/1 and printf/3.  Possible values are the atoms lf and
114    crlf.  The default for string and queue streams is lf, for other
115    streams it is operating-system dependent.
116
117<DT><STRONG>eof_action(Action)</STRONG><DD>
118    Controls how end-of-file is handled on this stream.  Possible values
119    are: 'eof_code' (return an code appropriate to the input predicate used
120    - this is the default), 'error' (raise an error), 'reset' (like eof_code,
121    but allow further read attempts on the stream).
122
123<DT><STRONG>event(Name)</STRONG><DD>
124    This option configures a read-queue stream or a socket stream to raise
125    the given event whenever data arrives on the previously empty stream.
126    This option is intended for queue streams in embedded applications
127    of ECLiPSe, or for socket streams in remote connection setups.  The
128    event handler should consume all data that is available on the stream.
129    Name must be an atom or an event handle.
130
131<DT><STRONG>flush(Where)</STRONG><DD>
132    This option affects only write-streams and allows to configure a
133    stream to automatically flush after every line written.  Where is
134    one of the atoms end_of_line (flush automatically after every
135    line) or flush (require explicit flushing).  The default setting
136    is flush, except for tty streams where the default is end_of_line.
137
138<DT><STRONG>macro_expansion(OnOff)</STRONG><DD>
139    Input streams only. Specifies whether term-macros (see macro/3) will
140    be expanded when reading from this stream using read/2, read_term/3 etc.
141    OnOff is one of the atoms on or off, the default is on.
142
143<DT><STRONG>output_options(OptionList)</STRONG><DD>
144    Write-streams only. Specifies the default output options that will be
145    used when printing terms onto this stream, e.g. using write/2.
146    The format of OptionList is the same as the one accepted by the
147    write_term/2,3 predicates.
148    Note that certain output predicates can override these default
149    settings, e.g. writeq/2, write_term/3, printf/3, etc.
150
151<DT><STRONG>reposition(Bool)</STRONG><DD>
152    The option reposition(true) verifies that the stream can be repositioned,
153    i.e. that seek/2 can be used on it.  Otherwise an error is raised.
154    The option reposition(false) has no effect.
155
156<DT><STRONG>yield(OnOff)</STRONG><DD>
157    This option is intended for queue streams in embedded applications
158    of ECLiPSe.  It configures the stream to yield control to the host
159    program whenever a read-queue reaches end-of-file or a write-queue
160    gets flushed.  See the Embedding Manual for more details.  OnOff
161    is one of the atoms on or off.
162
163</DL>
164
165<h3>Lifetime of Streams</h3>
166   A stream lives until it is closed.  Streams that are only referenced by
167   handle are closed automatically, either on failure across the open/3,4
168   predicate, or after all copies of their handle become unused and garbage
169   collected.  This means that no extra precautions have to be taken to
170   ensure that streams are closed on failure or when aborting.
171   Handle-streams can optionally be closed explicitly if their lifetime
172   is statically known in the program.  Streams that have aliases cannot
173   be closed automatically: all aliases must be closed explicitly.
174
175   NOTE: Stream handles are not normal Prolog terms!  They can not be
176   assembled, decomposed, or occur in Prolog text.
177<P>
178"),
179    args:["SourceSink" : "Atom, string or structure.",
180        "Mode" : "One of the atoms read, write, update, append.",
181        "Stream" : "Atom or variable.",
182        "Options" : "List."],
183    exceptions:[4 : "File or Mode is not instantiated.", 5 : "File is not an atom, string or structure.", 5 : "Mode is not an atom.", 5 : "Stream is not an atom or a variable.", 170 : "The operating system cannot open the file.", 192 : "Mode is an atom, but is not a valid mode."],
184    eg:"
185    See open/3.
186
187
188
189",
190        see_also:[open/3, existing_file/4, close/1, close/2,
191                set_stream_property/3, at / 2, at_eof / 1, current_stream / 1,
192                get_stream_info / 3, seek / 2, set_stream/2,
193                stream_select / 3, stream_truncate/1, flush / 1,
194                write_term/2, write_term/3]]).
195
196:- comment(get_stream_info / 3, [
197        summary:"Succeeds if the attribute Attr of the open stream Stream has the value
198Value.
199
200",
201        amode:(get_stream_info(+,-,-) is multi),
202        amode:(get_stream_info(+,+,-) is semidet),
203        desc:html("   Used to retrieve information associated to an open stream.  The
204   available attributes and their meanings are:
205
206<P>
207<PRE>
208    Attr            Value         Description
209
210    aliases         integer       current number of symbolic names
211
212    compress        on, off       a hint for output operations (e.g.
213                                  write_exdr/2) to use a more compact
214                                  output format (output streams only).
215                                  Default: on (file,pipe,socket) or off.
216
217    connection      atom          identification of the connected
218                                  socket - file name for unix sockets,
219                                  host name for internet ones
220
221    delete_file     off,          delete an opened file automatically when:
222                    when_lost,    - its stream handle becomes inaccessible
223                    when_closed   - the stream is closed in any way
224
225    device          file, null,   the device behind the stream
226                    pipe, queue,
227                    socket, tty,
228                    string
229
230    encoding        octet,        character encoding used by this stream
231                    iso_latin_1,
232                    ...
233
234    end_of_line     lf, crlf      which end-of-line sequence to write
235                                  (output streams only)
236
237    end_of_stream   at,not,past   indicates whether the stream is currently
238                                  positioned at (or past) the end-of-file
239
240    eof_action      eof_code,     how to react to end-of-file
241                    error,        (input streams only)
242                    reset
243
244    event           atom or       event on writing to empty stream
245                    event handle  (see open/4)
246
247    fd              integer       the associated OS file descriptor
248
249    flush           flush,        explicit or implicit flushing
250                    end_of_line   (output streams only)
251
252    handle          stream handle a garbage-collectable handle to the stream
253                                  (see also get_stream/2)
254
255    input           true, false   this is an input stream (ISO)
256
257    last_written    integer       character code of last written character
258                                  (output streams only)
259
260    line            integer       current line number
261                                  (input streams only)
262
263    mode            read, write,  the stream's direction
264                    update
265
266    name            atom or       associated filename, or contents
267                    string        (in case of a string or queue), or
268                                  pseudo file name (user, error, null)
269
270    macro_expansion on, off       expand term macros (input streams only)
271
272    offset          integer       current position in the
273                                  stream, as given by at/2
274
275    output          true, false   this is an input stream (ISO)
276
277    output_options  list          default output options for all term
278                                  output on this stream. The list
279                                  format is as in write_term/2,3.
280
281    physical_stream integer       associated stream number
282                                  (DEPRECATED: if this number is retrieved,
283                                  the system will no longer be able to close
284                                  the stream automatically when unused)
285
286    port            integer       port number associated with an
287                                  internet socket
288
289    prompt          string        prompt string (input streams only)
290
291    prompt_stream   handle        output stream for the prompt
292                                  (input streams only)
293
294    reposition      true, false   the stream can be repositioned (seek/2)
295
296    sigio           on            SIGIO signals enabled (UNIX only)
297
298    system_use      on, off       a system stream is currently
299                                  redirected to this stream
300
301    usable          on, off       if the stream can currently be used:
302                                  flushing or reading the empty stream
303                                  may not be properly handled if `off'.
304
305    yield           on, off       yield on end-of-file (see open/4)
306</PRE>
307"),
308        args:[
309            "Stream" : "Stream handle or alias (atom)",
310            "Attr" : "Atom or variable.", "Value" : "Variable, atom, string, integer or handle."],
311        fail_if:"Fails if the requested attribute is not available for this stream",
312        exceptions:[4 : "Stream is not instantiated.", 5 : "Stream is neither an atom nor a handle.", 5 : "Attr is instantiated, but not to an atom.", 5 : "Value is instantiated, but not to an atom, string, integer or handle.", 6 : "Attr is an atom, but not a valid attribute name.", 193 : "Stream does not denote an open stream."],
313        eg:"
314Success:
315    ?- get_stream_info(input,X,Y), writeln(X is Y), fail.
316    name is user
317    aliases is 2
318    system_use is on
319    line is 1
320    offset is 0
321    prompt is
322    prompt_stream is $&(stream(1))
323    fd is 0
324    reprompt_only is off
325    device is tty
326    mode is read
327    usable is on
328    macro_expansion is on
329    handle is $&(stream(0))
330    No (0.00s cpu)
331
332    ?- get_stream_info(toplevel_input, prompt, P).
333    P = \"\\t\"
334    Yes (0.00s cpu)
335
336Fail:
337    get_stream_info(output, prompt, P).
338    get_stream_info(output, system_use, off).
339
340Error:
341    get_stream_info(X, Y, Z).                      (Error 4)
342    get_stream_info(file(f), Y, Z).                (Error 5)
343    get_stream_info(output, 7, X).                 (Error 5)
344    get_stream_info(output, offset, 8.5).          (Error 5)
345    get_stream_info(output, length, Z).            (Error 6)
346    get_stream_info(nostream, Y, Z).               (Error 193)
347",
348        see_also:[set_stream_property/3, open / 3, open / 4, current_stream / 1, get_stream_info / 3, get_stream / 2, at / 2, write_term/2, write_term/3]]).
349
350:- comment(current_stream / 1, [
351        summary:"Succeeds if Stream is a currently open stream. ",
352        amode:(current_stream(+) is semidet),
353        amode:(current_stream(-) is nondet),
354        desc:html("
355   Used to test whether a given identifier or handle denotes an open stream,
356   or enumerates all currently open streams on backtracking.
357<P>
358   When called with a variable argument, only stream handles are returned,
359   not any symbolic aliases.
360<P>
361"),
362        args:["Stream" : "Variable, stream handle, or atom."],
363               fail_if:"Fails if Stream is instantiated but does not denote an open stream.",
364        exceptions:[5 : "Stream is instantiated, but not to an atom or stream handle."],
365        eg:"
366Success:
367    ?- current_stream(S), writeln(S), fail.
368    $&(stream(0))
369    $&(stream(1))
370    $&(stream(2))
371    $&(stream(3))
372    $&(stream(4))
373    $&(stream(5))
374    $&(stream(6))
375    $&(stream(8))
376    No (0.00s cpu)
377
378    ?- current_stream(output).
379    Yes (0.00s cpu)
380
381    ?- current_stream(junk).
382    No (0.00s cpu)
383",
384        see_also:[open / 3, open / 4, get_stream_info / 3, get_stream / 2]]).
385
386:- comment(accept / 3, [
387        summary:"Accepts a connection for a stream socket and creates a new socket which can
388be used for I/O.
389
390",
391        amode:(accept(+,-,-) is det),
392        amode:(accept(+,-,+) is det),
393        desc:html("\
394   accept/3 is a direct link to the accept(2) socket system call.
395   Stream must be a socket stream created with socket/3 or new_socket_server/3
396   of the type stream, listening for connections.  accept/3 blocks until
397   there is a connection request from another process, and then it creates
398   a new socket stream NewStream with the same properties as Stream, which
399   can be then used for communication with the connecting process.  The
400   Stream socket remains open and listening for further connections.
401
402<P>
403   In the internet domain, From is unified with the address of the
404   connecting process in the form HostName/Port.  In the unix domain, From
405   is unified with an empty atom ''.
406
407<P>
408   When instantiated, NewStream must be a symbolic stream name, i.e.  an
409   atom.  The stream can also be specified as sigio(NewStream).  In this
410   case the socket is created and in addition it is instructed to send the
411   signal io each time new data appears in it.
412
413<P>
414   Stream sockets are connected using the standard sequence, i.e.
415   socket/3, bind/2, listen/2 and accept/3 on the server and socket/3 and
416   connect/2 on the client.  After the sockets are connected, both
417   processes can use them for reading and writing.
418
419<P>
420"),
421        args:[
422            "Stream" : "Stream handle or alias (atom)",
423            "From" : "A term unifiable with a structure atom/integer.", "NewStream" : "Atom, structure or variable."],
424        exceptions:[4 : "Stream is not instantiated.", 5 : "Stream is instantiated, but not to an atom or a sigio/1    structure.", 5 : "From is instantiated but not to an atom or a structure.", 170 : "It was not possible to execute the system call."],
425        eg:"
426Success:
427      socket(internet, stream, s), bind(s, Addr), listen(s, 1),
428      accept(s, From, news).
429
430Error:
431      accept(s, From, 6)            (Error 5).
432      socket(internet, datagram, s), bind(s, Addr), listen(s, 2),
433      accept(s, From, news)         (Error 170).
434
435
436
437",
438        see_also:[socket / 3, bind / 2, listen / 2, connect / 2]]).
439
440:- comment(at / 2, [
441        summary:"Succeeds if Position is the position of the stream Stream.
442
443",
444        amode:(at(+,-) is det),
445        desc:html("\
446   Unifies Position with the position of the given Stream, which is
447   defined as follows:
448<UL><LI>
449   For file streams, Position is the position in the file (the offset in
450   bytes from the beginning of the file) where the next read/write operation
451   will occur.
452</LI><LI>
453   For tty read streams, Position is the number of bytes already read from
454   the tty. For tty write streams, Position is the number of bytes already
455   written to the tty.
456</LI><LI>
457   For pipe read streams, Position is the number of bytes already read from
458   the pipe. For pipe write streams, Position is the number of bytes already
459   written to the pipe.
460</LI><LI>
461   For socket streams, Position is the number of bytes already read from
462   the socket.
463</LI><LI>
464   For string streams, Position is the position in the string (the offset in
465   bytes from the beginning of the string) where the next read/write operation
466   will occur.
467</LI><LI>
468   For queue read streams, Position is always 0. For queue write and queue
469   update streams, Position is the number of unread bytes in the queue.
470</LI><LI>
471   For the null stream, Position is always 0.
472</LI></UL>
473
474   Stream can be a symbolic stream name or a stream handle.
475"),
476        args:[
477            "Stream" : "Stream handle or alias (atom)",
478            "Pointer" : "Integer or variable."],
479        exceptions:[4 : "Stream is not instantiated.", 5 : "Pointer is instantiated to a non-integer.", 5 : "Stream is instantiated to neither to an atom nor a stream handle.", 192 : "Stream is an illegal stream mode."],
480        eg:"
481Success:
482      ?- open(file1,write,S), at(S, P1),
483         write(S, 1234567890), at(S, P2), close(S).
484      P1 = 0
485      P2 = 10
486
487
488      ?- open(file1,update,S), at(S, P1), read(S, T),
489         at(S, P2), close(S).
490      P1 = 0
491      T = 1234567890
492      P2 = 10
493
494Error:
495      at(Stream, 4).      (Error 4).
496      at(\"3\", Position).   (Error 5).
497      at(7, 4.3).         (Error 5).
498",
499        see_also:[at_eof / 1, seek / 2]]).
500
501
502:- comment(at_eof / 1, [
503        summary:"Succeeds if the stream Stream is positioned at end of file. ",
504        amode:(at_eof(+) is semidet),
505        desc:html("\
506   Used to test if the input stream Stream is positioned at end of file.
507<UL><LI>
508   For file streams and string streams, this means that either the next read
509   operation will return an end-of-file condition, or end-of-file was already
510   read and the next read operation would result in a past-end-of-file error.
511</LI><LI>
512   For tty streams, it means only that there is currently no further input
513   available, and a subsequent read operation will prompt for more.
514</LI><LI>
515   For queue streams, it means only that the queue is currently empty.
516   The queue will recover from the end-of-file condition when new data
517   is written into it from the write end.
518</LI><LI>
519   For pipe and socket streams, this condition means that the next read
520   operation will either block or return an end-of-file condition.
521   To check whether there is any data to read, use stream_select/3.
522</LI><LI>
523   The null stream is always at end-of-file.
524</LI></UL>
525   Stream can be a symbolic stream name or a stream handle.
526"),
527        args:["Stream" : "Stream handle or alias (atom)"],
528        fail_if:"Fails if Stream is a file with its pointer not at end of file.",
529        exceptions:[4 : "Stream is not instantiated.", 5 : "Stream is instantiated, but not to an atom or a stream handle.", 192 : "Stream is an illegal stream mode."],
530        eg:"
531Success:
532      at_eof(null).
533
534      ?- open(file1,update,S), at_eof(S),
535         write(S,hello), at(S,5), at_eof(S), close(S).
536      yes.
537
538Fail:
539
540      ?- open(file1,write,S),write(S,hello), close(S),
541         open(file1,read,S), at_eof(S), close(S).
542      no.
543
544Error:
545      at_eof(X).                  (Error 4).
546      at_eof(\"s\").                (Error 5).
547      at_eof(not_a_stream).       (Error 192).
548
549
550
551",
552        see_also:[at / 2, seek / 2, stream_truncate/1]]).
553
554
555:- comment(bind / 2, [
556        summary:"Associates an address with a given socket stream. ",
557        amode:(bind(+,+) is det),
558        amode:(bind(+,-) is det),
559        desc:html("<P>
560   bind/2 is a direct link to the bind(2) socket system call.
561   Stream must be a socket stream created with socket/3.
562   If the socket was created in the unix domain, Address must be an atom
563   which identifies the file associated with the socket.  This file name
564   can then be used by other processes to connect with this socket using
565   the predicate connect/2.
566
567<P>
568   If the socket is in the internet domain, the address is in the form
569   HostName/Port, where any of Address or HostName or Port may be
570   uninstantiated.  When the port is already in use, the predicate raises
571   an error and so it is always safest to call bind/2 with Address
572   uninstantiated (this corresponds to the INADDR_ANY value for the system
573   call), and upon success it will be instantiated to the hostname and
574   selected port number.
575
576<P>
577   Stream sockets are connected using the standard sequence, i.e.
578   socket/3, bind/2, listen/2 and accept/3 on the server and socket/3 and
579   connect/2 on the client.  After the sockets are connected, both
580   processes can use them for reading and writing.
581
582<P>
583   Datagram sockets require a connect/2 call from the process that wants to
584   write on the socket and bind/2 from the one that reads from it.
585
586<P>
587"),
588        args:[
589            "Stream" : "Stream handle or alias (atom)",
590            "Address" : "Atom, structure or variable."],
591        exceptions:[4 : "Stream is not instantiated.", 5 : "Stream is instantiated, but not to an atom or a stream handle.", 5 : "Address is instantiated but not to the form accepted by the    socket domain.", 170 : "It was not possible to bind the socket."],
592        eg:"
593Success:
594
595Error:
596      bind(s, Host/p)               (Error 5).
597      bind(s, '/usr/bin')           (Error 170).
598
599",
600        see_also:[socket / 3, listen / 2, accept / 3, connect / 2, new_socket_server/3, current_stream / 1, get_stream_info / 3]]).
601
602
603:- comment(close / 2, [
604        summary:"Closes the stream specified by Stream.",
605        amode:(close(+,+) is det),
606        args:[ "Stream" : "Stream handle or alias (atom)",
607        	"Options" : "List of option terms"],
608        exceptions:[4 : "Stream is not instantiated.",
609	    4 : "Options is not sufficiently instantiated.",
610	    5 : "Stream is instantiated, but not to a stream handle or an atom.",
611%	    40 : "Stream is a handle that was already closed.",
612%	    193 : "Stream is an illegal stream specification.",
613	    196 : "Trying to close a system stream (handled by default)."],
614        desc:html("<P>
615	    The only supported option is force(true).  This will suppress
616	    any errors that would have been raised during closing otherwise,
617	    in particular errors from the operating system, or the stream
618	    being already closed.  It is intended for error handling
619	    routines that want to do their best to free resources.
620	<P>
621	    close(Stream,[]) is equivalent to close(Stream).
622	    See close/1 for more details.  
623	"),
624	eg:"
625	:- local finalization(
626		close(logstream, [force(true)])
627	    ).
628	",
629        see_also:[close/1, open / 3, open / 4]]).
630
631
632:- comment(close / 1, [
633        summary:"Closes the stream specified by Stream.  ",
634        amode:(close(+) is det),
635        desc:html("<P>
636   Used to explicitly close a stream.  Stream can be a symbolic stream name
637   or a stream handle.
638<P>
639   When Stream is a stream handle, the stream is closed, but any symbolic
640   stream aliases associated with it still refer to this (now closed) stream,
641   until they are either closed as well, or redirected to other streams.
642<P>
643   When Stream is a symbolic stream name, the stream gets closed (unless it
644   was already closed using a different alias or handle), and the alias gets
645   detached and no longer refers to a stream.
646<P>
647   If a stream has several aliases, every alias should be closed explicitly.
648   If a stream has handles and aliases, then only the aliases need to be
649   closed.  If a stream has only handles, it is enough to close it using
650   one of the handles.
651<P>
652   If a stream has only handles, it is actually not absolutely necessary
653   to close it at all: it will be closed automatically when the handles
654   become inaccessible, e.g. due to failure or garbage collection of the
655   handles.  In particular, it is NOT necessary to take precautions for
656   closing a stream in case of failure or abort across the stream opening.
657<P>
658   The predefined stream aliases and the standard streams always remain
659   open.  Trying to close them has the following effect:
660   <DL><DT>
661   Current streams (input, output, warning_output, log_output, error):</DT><DD>
662       the stream is closed (unless it was directed to a standard stream),
663       and the alias is reset to the corresponding user_XXX alias</DD><DT>
664   Default streams (user_input, user_output, user_error):</DT><DD>
665       the stream is closed (unless it was directed to a standard stream),
666       and the alias is reset to the corresponding stdXXX alias</DD><DT>
667   Standard streams (stdin, stdout, stderr, null):</DT><DD>
668       no effect</DD>
669   </DL>
670<P>
671"),
672        args:[ "Stream" : "Stream handle or alias (atom)"],
673        exceptions:[4 : "Stream is not instantiated.",
674	    5 : "Stream is instantiated, but not to a stream handle or an atom.",
675	    40 : "Stream is a handle that was already closed.",
676	    170 : "Operating system could not close the stream.",
677	    193 : "Stream is an illegal stream specification.",
678	    196 : "Trying to close a system stream (handled by default)."],
679        eg:"
680      % Open and close using a handle
681      ?- open(file1,write,S), write(S,hello), close(S).
682      Yes (0.00s cpu)
683
684      % Open and close using an alias name
685      ?- open(file1,write,a), write(a,hello), close(a).
686      Yes (0.00s cpu)
687
688      % WRONG: Closing the stream via handle, but not closing the alias:
689      % (alias refers to a closed stream)
690      ?- open(file1,write,S), set_stream(a,S), write(a,hello),
691         close(S), write(a, world).
692      illegal stream mode in write(a, world)
693      Abort
694
695      % OK: Closing the stream via its alias only:
696      ?- open(file1,write,S), set_stream(a,S), write(a,hello),
697         close(a), write(a, world).
698      illegal stream specification in write(a, world)
699      Abort
700
701      % OK: handle-only stream gets auto-closed on abort
702      ?- open(file1, read, S), abort.
703      Abort
704
705      % OK: handle-only stream gets auto-closed on failure
706      ?- open(file1, read, S), fail.
707      No (0.00s cpu)
708
709      % OK: handle-only stream gets auto-closed on abort (and file deleted)
710      ?- open(file2, write, S, [delete_file(when_lost)]), abort.
711      Abort
712
713      % OK: handle-only stream gets auto-closed on failure (and file deleted)
714      ?- open(file2, write, S, [delete_file(when_lost)]), fail.
715      No (0.00s cpu)
716
717
718Error:
719      close(Stream).         (Error 4).
720      close(\"4\").            (Error 5).
721      close(S),close(S).     (Error 40).
722      close(10).             (Error 193).
723      close(nostream).       (Error 193).
724      close(output).         (Error 196).
725",
726        see_also:[close /2, open / 3, open / 4, set_stream / 2]]).
727
728:- comment(connect / 2, [
729        summary:"Connects a socket with the given address.
730
731",
732        amode:(connect(+,+) is det),
733        desc:html("<P>
734   connect/2 is a direct link to the connect(2) socket system call.
735   Stream must be a socket stream created with socket/3.
736   If the socket was created in the unix domain, Address must be an atom
737   which identifies the file associated with the socket.  If Address is 0
738   and socket type is datagram, the socket is disconnected.
739
740<P>
741   If the socket is in the internet domain, the address is in the form
742   HostName/Port, where the atom HostName denotes the host to be connected
743   on the given integer port Port.  If Address is 0/0 and socket type is
744   datagram, the socket is disconnected.
745
746<P>
747   Every socket communication in ECLiPSe requires at least one of every two
748   communicating processes to call connect/2, because system calls to
749   perform direct datagram addressing are not available.  The socket
750   connection can be queried with get_stream_info(s, connection, C).
751
752<P>
753   Stream sockets are connected using the standard sequence, i.e.
754   socket/3, bind/2, listen/2 and accept/3 on the server and socket/3 and
755   connect/2 on the client.  After the sockets are connected, both
756   processes can use them for reading and writing.
757
758<P>
759   Datagram sockets require a connect/2 call from the process that wants to
760   write on the socket and bind/2 from the one that reads from it.
761
762<P>
763   If a system interface error (170) is raised while calling connect/2, the
764   socket will be automatically closed. This is to get around a problem
765   where the connect(2) system call can leave the socket in an incorrect
766   state on some operating systems. 
767
768<P>
769"),
770        args:[
771            "Stream" : "Stream handle or alias (atom)",
772            "Address" : "Atom, integer or structure."],
773        exceptions:[4 : "Stream or Address is not instantiated.", 5 : "Stream is instantiated, but not to an atom or a stream handle.", 5 : "Address is instantiated but not to the form accepted by the    socket domain.", 6 : "Address is a nonzero integer.", 170 : "It was not possible to connect the socket."],
774        see_also:[socket / 3, listen / 2, accept / 3, connect / 2, current_stream / 1, get_stream_info / 3]]).
775
776:- comment(flush / 1, [
777        summary:"Flushes the output stream Stream.  ",
778        amode:(flush(+) is det),
779        desc:html("<P>
780   Used to flush any data contained in the Stream buffer of an output stream.
781   Flushing means that the data is transferred from a memory buffer to the
782   operation system's I/O system.
783<P>
784   Buffers are normally only flushed when they get full, or when the stream
785   is closed.  Explicit flushing in between reduces performance, but sometimes
786   it is desirable to make sure that data is actually written at certain points.
787<P>
788   Note that streams can be also be configured to flush automatically at
789   every newline, using the flush(end_of_line) option.
790<P>
791   Stream can be a symbolic stream name (atom) or a stream handle.
792<P>
793"),
794        args:["Stream" : "Stream handle or alias (atom)"],
795        exceptions:[4 : "Stream is not instantiated.", 5 : "Stream is instantiated neither to a stream handle nor an atom.", 192 : "Stream is not an output stream."],
796        eg:"
797Success:
798      flush(output).
799      flush(null).
800
801
802Error:
803      flush(Stream).            (Error 4).
804      flush(\"Stream\").          (Error 5).
805      flush(12).                (Error 192). % no such stream
806      flush(debug_input).       (Error 192). % input stream
807",
808        see_also:[set_stream_property/3, open / 3, open / 4, close / 1, tyo / 2]]).
809
810
811:- comment(get_stream / 2, [
812        summary:"Succeeds if Stream is the stream to which the stream StreamId is assigned. ",
813        amode:(get_stream(+,-) is det),
814        amode:(get_stream(+,+) is semidet),
815        desc:html("<P>
816   StreamId is an existing symbolic stream alias or a stream handle.
817   If Stream is a variable, it will get bound to a stream handle corresponding
818   to StreamId.  If Stream is a symbolic stream alias or a handle, then
819   the predicate succeeds iff StreamId and Stream denote the same stream.
820<P>
821   The predefined symbolic system stream names are:
822<P>
823   input, output, error, warning_output, log_output,
824   stdin, stdout, stderr, null
825<P>
826"),
827        args:[
828            "StreamId" : "Stream alias (atom), or handle",
829            "Stream" : "Variable, stream handle or alias (atom)"],
830        fail_if:"Fails if Stream is not a stream with the stream identifier StreamId",
831        exceptions:[4 : "One or both of StreamId and Stream is not instantiated.", 5 : "Stream is neither an atom, a stream handle nor a variable.", 5 : "StreamId is neither an atom nor a stream handle.", 193 : "StreamId is an illegal stream specification."],
832        eg:"
833Success:
834      ?- get_stream(input,S).
835      S = $&(stream(0))
836      Yes (0.00s cpu)
837
838      ?- set_stream(a,input), get_stream(input,a), get_stream(a,input).
839      Yes (0.00s cpu)
840
841Fail:
842      set_stream(b,input), get_stream(b,output).
843
844Error:
845      get_stream(Id, S).      (Error 4).
846      get_stream(1.0,S).      (Error 5).
847      get_stream(3, S).       (Error 5).
848      get_stream(blah,S).     (Error 193). % does not exist
849",
850        see_also:[set_stream / 2]]).
851
852
853:- comment(listen / 2, [
854        summary:"Specifies how many connections are accepted for a socket and makes
855connections available.
856
857",
858        amode:(listen(+,+) is det),
859        desc:html("<P>
860   listen/2 is a direct link to the listen(2) socket system call.
861   Stream must be a socket stream created with socket/3
862   of the type stream.  Queue specifies the length of the connection queue,
863   i.e.  how many connections are allowed for this socket.  After the call
864   to listen/2, other processes can call connect/2 to connect with this
865   socket, but the I/O is possible only after the server process creates
866   the new socket using accept/3.
867
868<P>
869   Stream sockets are connected using the standard sequence, i.e.
870   socket/3, bind/2, listen/2 and accept/3 on the server and socket/3 and
871   connect/2 on the client.  After the sockets are connected, both
872   processes can use them for reading and writing.
873
874<P>
875"),
876        args:["Stream" : "Stream handle or alias (atom)", "Queue" : "An integer."],
877        exceptions:[4 : "Stream or Queue is not instantiated.", 5 : "Stream is instantiated, but not to an atom or a stream handle.", 5 : "Queue is instantiated but not to an integer.", 170 : "It was not possible to execute the system call."],
878        eg:"
879Success:
880      socket(internet, stream, s), bind(s, Addr), listen(s, 1).
881
882Error:
883      listen(s, N)                  (Error 4).
884      listen(s, 1.0)                (Error 5).
885      listen(null, 2)               (Error 170).
886",
887        see_also:[socket / 3, bind / 2, accept / 3, connect / 2, new_socket_server/3]]).
888
889
890:- comment(open / 3, [
891        summary:"Opens the I/O source or sink SourceSink in mode Mode and associates it
892with the stream identifier Stream.  ",
893        amode:(open(++,+,-) is det),
894        amode:(open(++,+,+) is det),
895        desc:html("   This predicate opens an ECLiPSe I/O stream.
896
897<P>
898   The most common use is for opening files. In this case, SourceSink
899   is a file name (atom or string).
900
901<P>
902   Mode is one of the following
903
904<P>
905<PRE>
906    read         open for reading
907    write        open for writing
908    update       open for reading and writing
909    append       open for writing at the end
910</PRE>
911   A file must already exist if it is to be opened in read mode.  A file
912   opened in append mode is opened in write mode at the end of the file.
913   If an existing file is opened in write mode, it is truncated to zero
914   size, i.e. its previous content is lost.
915
916<P>
917   If Stream is a variable, it will be instantiated to a system-generated
918   stream handle.  This handle can subsequently be used to identify the
919   stream.  If Stream is an atom, then this atom will be used as a symbolic
920   alias name for the stream (like with the alias(Name) option of open/4,
921   or set_stream/2).  The use of handles should be preferred.
922
923<P>
924   If SourceSink is of the form string(InitialString), then a so-called
925   string stream is opened.  A string stream is basically an in-memory
926   file and its initial contents is the string InitialString.
927   A string stream can be used like any other stream, i.e. it is possible
928   to read, write and seek like on a true file.
929   The current contents of a string stream can at any time be retrieved
930   as a whole using get_stream_info(Stream, name, Contents).
931
932<P>
933   If SourceSink is of the form queue(InitialString), then a queue
934   stream is opened. It behaves like a string that can be written at the
935   end and read from the beginning.  Seeking is not allowed on queues.
936   The current contents of a queue can at any time be retrieved as a
937   whole using get_stream_info(Stream, name, Contents). Queues are
938   considered to be at end-of-file while they are empty. 
939   Queues can be configured to raise an event every time something
940   is written to the previously empty queue (see open/4).
941
942<P>
943   If SourceSink is of the form fd(Integer), then the stream in opened
944   onto an existing operating system file descriptor.
945
946<h3>Lifetime of Streams</h3>
947   A stream lives until it is closed.  Streams that are only referenced by
948   handle are closed automatically, either on failure across the open/3,4
949   predicate, or after all copies of their handle become unused and garbage
950   collected.  This means that no extra precautions have to be taken to
951   ensure that streams are closed on failure or when aborting.
952   Handle-streams can optionally be closed explicitly if their lifetime
953   is statically known in the program.  Streams that have aliases cannot
954   be closed automatically: all aliases must be closed explicitly.
955
956   NOTE: Stream handles are not normal Prolog terms!  They can not be
957   assembled, decomposed, or occur in Prolog text.
958<P>
959"),
960        args:["SourceSink" : "Atom, string or structure.", "Mode" : "One of the atoms read, write, update, append.", "Stream" : "Atom or variable."],
961        exceptions:[4 : "File or Mode is not instantiated.", 5 : "File is not an atom, string or structure.", 5 : "Mode is not an atom.", 5 : "Stream is not an atom or a variable.", 170 : "The operating system cannot open the file.", 192 : "Mode is an atom, but is not a valid mode."],
962        eg:"
963    ?- open(file1, write, S), write(S, foo), close(S).
964    S = $&(stream(closed))
965    yes.
966
967    ?- open(file1, update, S), read(S,X), write(S,bar), close(S).
968    X = foo
969    S = $&(stream(closed))
970    yes.
971
972    ?- open(file1, append, S), write(S, baz), close(S).
973    S = $&(stream(closed))
974    yes.
975
976    ?- open(file1, read, mystr), read(mystr,X), close(mystr).
977    X = foobarbaz
978    yes.
979
980
981    ?- open(string(\"foo\"), update, S),
982                 read(S,X), write(S,bar),
983                 get_stream_info(S, name, Contents), close(S).
984    X = foo
985    Contents = \"foobar\"
986    yes.
987
988    ?- open(queue(\"\"), update, S),
989                 write(S, hello), read(S, X), close(S).
990    X = hello
991    yes.
992
993    ?- event_create(writeln(my_event_handler), Event),
994                 open(queue(\"\"), write, S, [event(Event)]),
995                 write(S, hello).
996    my_event_handler
997    S = $&(stream(7))
998    yes.
999
1000Error:
1001       open(Var,update,s).      (Error 4).
1002       open(file1,Mode,s).      (Error 4).
1003       open(2,update,s).        (Error 5).
1004       open(file1,\"str\",s).     (Error 5).
1005       open(file1,update,9).    (Error 5).
1006       open(nonex,read,s).      (Error 170). % no such file
1007       open(file1,atom,s).      (Error 192). % no such mode
1008",
1009    see_also:[open/4, existing_file/4, close/1, set_stream/2,
1010        at / 2, at_eof / 1, current_stream / 1, get_stream_info / 3, seek / 2, stream_select / 3, stream_truncate/1]]).
1011
1012
1013:- comment(seek / 2, [
1014        summary:"The pointer in stream Stream is offset Offset from the start of the file",
1015
1016        amode:(seek(+,+) is det),
1017        desc:html("   Moves the file pointer to offset Offset from the start of the file
1018   opened.  It is an error if Stream is not a stream or if Offset is not an
1019   integer or the atom 'end_of_file'.
1020
1021<P>
1022   seek/2 seeks to the end of the file when Offset is instantiated to
1023   end_of_file.
1024
1025<P>
1026   Only file and string streams are seekable.
1027   seek/2 has no effect on the null stream, it always succeeds.
1028<P>
1029"),
1030        args:[
1031            "Stream" : "Stream handle or alias (atom)",
1032            "Offset" : "Integer or the atom end_of_file."],
1033        exceptions:[4 : "Either Stream or Offset is uninstantiated.",
1034            5 : "Offset is instantiated, but not to an integer or the atom end_of_file.",
1035            5 : "Stream is instantiated, but not to an atom or a stream handle.",
1036            6 : "Offset is a negative integer or greater than the file length.",
1037            192 : "Stream is not seekable.",
1038            193 : "Stream is an illegal stream specification."],
1039        eg:"
1040Success:
1041      seek(0, null). % does not modify, only succeeds
1042
1043      ?- open(file1,update,S), write(S,hello),
1044         seek(S,3), read(S,T), close(S).
1045      T = lo
1046      yes.
1047
1048Error:
1049      seek( Offset,7).      (Error 4).
1050      seek(\"7\", 2).         (Error 5).
1051      seek(7, -1).          (Error 6).
1052      seek( 0,input).       (Error 192).
1053      seek(-1, 0).          (Error 193). % does not exist
1054",
1055        see_also:[at / 2, at_eof / 1, set_stream_property/3]]).
1056
1057
1058:- comment(stream_select / 3, [
1059        summary:"Returns streams from StreamList which are ready for I/O, blocking at most
1060Timeout seconds.  ",
1061        amode:(stream_select(++,+,-) is det),
1062        desc:html("\
1063   stream_select/3 is modelled after (and partially implemented using) the
1064   select() Unix system call.  StreamList is a list of streams where
1065   input or output is expected to occur.  If I/O is available on some
1066   streams from the StreamList, ReadyStreams is unified with a list of
1067   those. The same symbolic stream names are used in both lists.
1068
1069<P>
1070   If Timeout is a number, it must be non-negative and less than
1071   100000000. stream_select/3 then waits for at most Timeout seconds for I/O
1072   on these streams and if none is available, it unifies ReadyStreams
1073   with nil.  If Timeout is zero, stream_select/3 does not wait but it
1074   immediately returns the list of streams where I/O is available.  If
1075   Timeout is the atom 'block', stream_select/3 waits until I/O is possible
1076   on one of the streams in StreamList.
1077
1078<P>
1079   The streams in StreamList can be sockets, queues, string streams or
1080   the null stream.  On Unix systems, pipes, files and ttys are also
1081   allowed.  On Windows, ttys (the console) is also allowed, but only
1082   when timeout is 0.
1083
1084<P>
1085Notes:
1086<UL>
1087<LI>
1088   Sockets are only considered ready when input (rather than output) is
1089   possible.
1090</LI><LI>
1091   The null stream is never ready.
1092</LI><LI>
1093   Unlike the select() system call, stream_select/3 does not test any
1094   exceptional pending conditions on sockets.
1095</LI>
1096</UL>
1097
1098<P>
1099"),
1100        args:["StreamList" : "A list of atoms (stream aliases) or stream handles.",
1101            "Timeout" : "A number or an atom.",
1102            "ReadyStreams" : "A term unifiable with a list of atoms or stream handles."],
1103        exceptions:[4 : "StreamList is not instantiated or it contains uninstantiated    variables.",
1104            4 : "Timeout is not instantiated.",
1105            5 : "StreamList is not a list of stream handles and atoms.",
1106            5 : "Timeout instantiated, but not to a number or an atom.",
1107            5 : "ReadyStreams is instantiated, but not to a list or nil",
1108            6 : "Timeout is a negative number or an atom different from block.", 
1109            141 : "Not implemented for this stream class on this system.",
1110            170 : "The system call was interrupted by a signal.",
1111            192 : "A stream in StreamList is not an input stream or a pipe,    or it is a string stream or null.",
1112            193 : "A stream in StreamList is not open or does not exist."],
1113        eg:"
1114     ?- socket(internet, datagram, s), bind(s, _/40000),
1115        socket(internet, datagram, r), bind(r, _/40001),
1116        stream_select([s, r], block, Streams).
1117
1118     <blocks until data arrives>
1119
1120
1121
1122     ?- open(queue(\"\"), update, q).
1123     yes.
1124
1125     ?- stream_select([q],0,L).
1126     L = []
1127     yes.
1128
1129     ?- write(q,hello).
1130     yes.
1131
1132     ?- stream_select([q],0,L).
1133     L = [q]
1134     yes.
1135",
1136        see_also:[open / 3, open / 4, socket / 3, get_stream_info / 3]]).
1137
1138
1139:- comment(set_stream / 2, [
1140        summary:"The symbolic stream name Alias is associated with the stream Stream.  ",
1141        amode:(set_stream(+,+) is det),
1142        index:["stream alias", "stream redirection"],
1143        desc:html("\
1144   This predicate is used to create new symbolic names (aliases) for streams,
1145   or to redirect existing symbolic stream names to other streams.
1146<P>
1147   If Alias is a new user-defined stream name, then that new name is
1148   associated with the stream denoted by the Stream.  Stream can be given
1149   in the form of a stream handle or an already existing alias name.
1150<P>
1151   If Alias is an already existing stream name (including one of the
1152   symbolic system stream names like input, output, error, warning_output,
1153   log_output), then that stream is redirected to Stream.  Note that the
1154   setting of the 'input' and 'output' aliases determines the streams used
1155   by the I/O predicates that have no stream argument.
1156<P>
1157   Any previous association of the name Alias is forgotten.  Other alias
1158   names for the same physical stream are not affected by redirection.
1159<P>
1160   When a user-defined symbolic stream is closed, the associated physical
1161   stream is closed and the association forgotten.
1162   Note that it is not enough to close the stream only via a handle, because
1163   the association of symbolic an physical stream remains (even though the
1164   physical stream is closed) until the stream alias is closed as well.
1165   A system-defined stream alias however will be automatically redirected
1166   back to its default when the associated physical stream is closed.
1167<P>
1168   An anonymous stream handle associated with a symbolic stream name can be
1169   obtained using get_stream/2 or get_stream_info/3.
1170<P>
1171   An alternative way of creating a stream alias is to specify it during
1172   stream creation, i.e. as the Stream-argument to open/3, socket/3, etc.,
1173   or by using an alias(Alias) option in open/4.
1174<P>
1175   The standard stream aliases stdin, stdout, stderr and null cannot be
1176   redirected.
1177<P>
1178"),
1179        args:["Alias" : "Atom.",
1180            "Stream" : "Stream handle or alias (atom)"],
1181        exceptions:[4 : "Either Alias or Stream is uninstantiated.",
1182		5 : "Either Alias is not an atom or Stream is not a stream handle or symbolic stream name.",
1183		193 : "Stream is an illegal stream specification.",
1184		196 : "Stream is fixed system stream."
1185		],
1186        eg:"
1187        % suppress standard output temporarily:
1188        ?- set_stream(output, null).
1189        Yes (0.00s cpu)
1190        ?- writeln(hello).
1191        Yes (0.00s cpu)
1192
1193        % set standard output back to default:
1194        ?- set_stream(output, stdout).
1195        Yes (0.00s cpu)
1196        ?- writeln(hello).
1197        hello
1198        Yes (0.00s cpu)
1199
1200        % alias the names s and output:
1201        ?- open(file1,update,s), set_stream(output,s),
1202           writeln(output,hi), flush(output).
1203        yes.
1204        ?- seek(s,0), read(s,X).
1205        X = hi
1206        yes.
1207
1208Error:
1209        set_stream(a, S).        (Error 4).
1210        set_stream(1.0, S).      (Error 5).
1211        set_stream(a, nonex).    (Error 193).
1212",
1213        see_also:[open / 4, get_stream / 2]]).
1214
1215
1216:- comment(socket / 3, [
1217        summary:"Creates a socket of a given type and domain and associates a stream with
1218it.  ",
1219        amode:(socket(+,+,-) is det),
1220        amode:(socket(+,+,+) is det),
1221        desc:html("<P>
1222   socket/3 is a direct link to the socket(2) socket system call.
1223   Domain is either unix or internet, type is stream or
1224   datagram.  It creates a socket of the given type in the given domain and
1225   creates a stream associated with it.  After the connection is
1226   established using bind/2, connect/2, listen/2 and/or accept/3, the
1227   stream can be used for input and output to communicate with other
1228   processes.
1229
1230<P>
1231   The unix domain can be used for communication between processes on the
1232   same machine, whereas the internet domain can connect any two machines.
1233   The stream type supports point-to-point reliable communication, whereas
1234   the datagram communication is a network-type communication with clear
1235   message boundaries, which, however, are not visible in ECLiPSe .
1236
1237<P>
1238   Note that in order to read data using read/1,2, it must have been
1239   written in Prolog term format (i.e.  ended with a period and a blank
1240   space character).  The output to sockets is buffered, so that data might
1241   be actually written only after a call to flush(Stream).
1242
1243<P>
1244   When instantiated, Stream must be the symbolic stream name (atom).  The
1245   stream can also be specified as sigio(Stream).  In this case the socket
1246   is created and in addition it is instructed to send the signal io each
1247   time new data appears in it.
1248
1249<P>
1250"),
1251        args:["Domain" : "Atom", "Type" : "Atom", "Stream" : "Atom, structure or variable."],
1252        exceptions:[5 : "Stream is instantiated, but not to an atom or a sigio    structure.", 5 : "Domain or Type are instantiated but not to atoms.", 6 : "Domain or Type are atoms, but different from the accepted    ones.", 170 : "It was not possible to create the socket."],
1253        eg:"
1254Success:
1255      socket(unix, stream, s).
1256      socket(internet, datagram, socket).
1257
1258Error:
1259      socket(unix, stream, 1)       (Error 5).
1260      socket(telnet, datagram, X)   (Error 6).
1261",
1262        see_also:[bind / 2, listen / 2, accept / 3, connect / 2, new_socket_server/3, exec / 2]]).
1263
1264
1265:- comment(set_stream_property / 3, [
1266        summary:"Sets the property Prop of the stream Stream to the value Value.  ",
1267        amode:(set_stream_property(+,+,+) is det),
1268        desc:html("   Used to set various stream properties:
1269
1270<P>
1271<PRE>
1272    Prop            Value         Description
1273
1274    compress        on, off       a hint for output operations (e.g.
1275                                  write_exdr/2) to use a more compact
1276                                  output format (output streams only).
1277                                  Default: on (file,pipe,socket) or off.
1278
1279    delete_file     off,          delete an opened file automatically when:
1280                    when_lost,    - its stream handle becomes inaccessible
1281                    when_closed   - the stream is closed in any way
1282
1283    end_of_line     lf, crlf      which end-of-line sequence to write
1284
1285    eof_action      eof_code,     how to react to end-of-file
1286                    error,        (input streams only)
1287                    reset
1288
1289    event           atom or       event on writing to empty stream
1290                    event handle  (see open/4)
1291
1292    flush           flush,        explicit or implicit flushing
1293                    end_of_line
1294
1295    macro_expansion on, off       expand term macros (input streams only)
1296
1297    offset          integer       current position in the
1298                                  stream, same as seek/2
1299
1300    output_options  list          default output options for all term
1301                                  output on this stream. The list
1302                                  format is as in write_term/2,3.
1303
1304    prompt          string        prompt string (input streams only)
1305
1306    prompt_stream   handle        output stream for the prompt
1307                    or atom       (input streams only)
1308
1309    sigio           on, off       enable/disable SIGIO signals on
1310                                  this stream (UNIX only)
1311
1312    yield           on, off       yield on end-of-file (see open/4)
1313
1314</PRE>
1315"),
1316        args:[
1317            "Stream" : "Stream handle or alias (atom)",
1318            "Prop" : "Atom.", "Value" : "atom, string, handle or integer."],
1319        exceptions:[4 : "Stream, Prop or Value is not instantiated.", 5 : "Stream is neither an atom nor a stream handle.", 5 : "Prop is instantiated, but not to an atom.", 5 : "Value is of the wrong type for the given property.", 6 : "Prop is an atom, but not a settable property.", 6 : "Value is not recognised for the given property.", 193 : "Stream does not denote an open stream."],
1320        eg:"
1321Success:
1322    set_stream_property(input, prompt, \"hello: \").
1323    set_stream_property(Stream, flush, end_of_line).
1324    set_stream_property(Stream, end_of_line, crlf).
1325
1326",
1327        see_also:[open / 3, open / 4, current_stream / 1, seek / 2, get_stream_info / 3, write_term/2, write_term/3]]).
1328
1329
1330
1331:- comment(new_socket_server/3, [
1332   args: ["Socket": "Socket server name (atom or variable)",
1333          "Address": "Address for socket connection (Host/Port or variable)",
1334          "Queue":  "Number of connections allowed (integer)"
1335         ],
1336   amode:(new_socket_server(-,?,+) is det),
1337   amode:(new_socket_server(+,?,+) is det),
1338   see_also: [accept/3, socket/3, bind/2, listen/2],
1339   summary: "Opens a new IP socket server stream with a maximum of Queue connections.",
1340   desc:  html("\
1341   <P> Opens a new IP stream socket server Socket at host Host and port number
1342   Port. It is allowed a maximum of Queue connection requests.
1343   This predicate combines the calls to socket/3, bind/2, listen/2 as follows:
1344   <PRE>
1345       new_socket_server(Soc, Address, N) :-
1346           socket(internet, stream, Soc), 
1347           bind(Soc, Address),
1348           listen(Soc, N).
1349   </PRE>
1350</P><P>
1351   After creation of the socket server, accept/2 can be called to
1352   accept client socket stream connections.  Socket is closed if
1353   either the bind/2 or listen/2 calls throws an exception and thus a
1354   server socket cannot be made.
1355</P>
1356"),
1357eg:  "
1358
1359% Set up a socket server and accept a socket connection. The following will
1360% print the Port number used for the server, and waits for a client connection
1361[eclipse 26]: new_socket_server(Server, localhost/Port, 1), writeln(Port), accept(Server, _, Socket).
136227694
1363....
1364
1365% On a different ECLiPSe process running on the same machine (as localhost
1366% is used for the host name)
1367
1368socket(internet, stream, Client), connect(Client, localhost/27694).
1369
1370Client = 9
1371Yes (0.00s cpu)
1372[eclipse 3]: 
1373...
1374
1375% On the original ECLiPSe process, the accept/3 call will now return
1376[eclipse 26]: new_socket_server(Server, localhost/Port, 1), writeln(Port), accept(Server, _, Socket).
137727694
1378
1379Port = 27694
1380Server = 9
1381Socket = 11
1382Yes (0.00s cpu)
1383% The Server can now be closed while the socket stream remains connected
1384[eclipse 27]: close(9).
1385
1386"
1387]).
1388
1389
1390
1391:- comment(stream_truncate / 1, [
1392        summary:"Truncate Stream at the current position",
1393        amode:(stream_truncate(+) is det),
1394        desc:html("\
1395    Used to truncate a stream, i.e. to remove all contents beyond the
1396    current (write) position.  As a consequence, immediately after this
1397    operation the stream is at end of file.
1398    <P>
1399    This operation only makes sense on file-streams and string streams
1400    which are open for writing (or updating). On all other types of streams,
1401    the predicate silently succeeds.
1402    <P>
1403    Files will be physically truncated, i.e. their size is trimmed and extra
1404    disk space returned to the operating system. String streams will free
1405    any unnecessary buffer memory.
1406    <P>
1407    Note: When opening an existing file for writing (not updating), the
1408    file is automatically truncated to size zero (see open/3,4).
1409"),
1410        args:["Stream" : "Stream handle or alias (atom)"],
1411        exceptions:[4 : "Stream is not instantiated.",
1412                5 : "Stream is instantiated, but not to an atom or a stream handle.",
1413                192 : "Stream is not open in write mode."],
1414        eg:"
1415        ?- open(string(\"hellothere\"), update, s).
1416        Yes (0.00s cpu)
1417
1418        ?- seek(s, 5).
1419        Yes (0.00s cpu)
1420
1421        ?- at_eof(s).
1422        No (0.00s cpu)
1423
1424        ?- stream_truncate(s).
1425        Yes (0.00s cpu)
1426
1427        ?- at_eof(s).
1428        Yes (0.00s cpu)
1429
1430        ?- seek(s,0).
1431        Yes (0.00s cpu)
1432
1433        ?- read_string(s, end_of_file, _, S).
1434        S = \"hello\"
1435        Yes (0.00s cpu)
1436",
1437        see_also:[at_eof / 1, seek / 2, open/3, open/4]]).
1438
1439