previous next top contents index framed top this page unframed
| Note: The low-level streams PROCEDUREs are subject to change. RPC is sufficiently high-level that it is unlikely to experience significant change. Accordingly, RPC should be used in preference to low-level PROCEDUREs. Low-level streams PROCEDUREs should be used only when necessary, and the programmer should isolate such use so that changes in their formulation will be easily tracked in the application. |
10.1. Low-Level Stream I/O PROCEDURE Conventions
Stream I/O consists of a flow of eight-bit character units.
I/O to streams may be
done to or from a supplied buffer, STRING,
or an individual character.
The type of buffer determines how the characters in the stream are
interpreted and therefore how they
are packed into the buffer or removed
from the buffer.
10.1.1. Timeouts
Associated with each I/O PROCEDURE is a
LONG INTEGER timeout value, the
number of milliseconds to wait for the operation to complete.
The timeout value may be a positive
LONG INTEGER to cause the PROCEDURE
to time out after that number of milliseconds, or one of the
constants shown in Figure 10–1.
If timeout is omitted or $block is given, the PROCEDURE blocks indefinitely until something can be input/output or an error occurs. If timeout is greater than zero, it specifies a minimum amount of time in milliseconds to wait before returning a timeout failure. If timeout is $poll, the PROCEDURE returns immediately with either a success value or one of the error values described below, as applicable. $poll should always be used in conjunction with the errorOK bit. If the errorOK bit is not set and no I/O is ready, STREAMS PROCEDUREs call errMsg with a fatal error, even if the timeout value is $poll. If the timeout value is $poll and nothing is ready, the STREAMS PROCEDUREs in question return $timedOut.
If the system does not support timeout, i.e., if
$systemSupportsTimeout returns FALSE,
all timeout values are treated
as if they were $block and the
PROCEDURE does not return until the I/O
is complete or an error occurs.
10.1.2. Success and Failure of I/O Operations
The I/O PROCEDUREs return a
LONG INTEGER that is nonnegative to
indicate success and negative to indicate failure. Unless the bit
errorOK is given to the PROCEDURE, however,
errMsg is called with
the fatal bit if a failure of any kind occurs.
The macros shown in Figure 10–2 are defined to test the return values.
Figure 10–2. Error Testing Macros
BOOLEAN
<macro> $success (LONG INTEGER ee);
# ee is return from stream PROCEDURE; returns TRUE
# iff PROCEDURE succeeded
COMPILETIME
LONG INTEGER
<macro> $error; # General error occurred
COMPILETIME
LONG INTEGER
<macro> $eos; # End of stream occurred
COMPILETIME
LONG INTEGER
<macro> $timedOut; # Operation timed out
A return of $error indicates a general error. A return of $timedOut indicates that the I/O operation did not occur because the timeout value was exceeded. A return of $eos indicates that no more data are available on input, or that no more data can be accepted by the other end on output.
The character-reading PROCEDURE $cReadStream returns INTEGER instead of LONG INTEGER values but is otherwise similar in this respect.
If an error return of any kind occurs,
the field $lastInputError or
$lastOutputError of the stream contains
a description of the error.
If the operation is neither input nor output,
$lastInputError is set.
10.1.3. The General Error Return ($error)
The general error return occurs if the error does not fit one of the
other error categories, or if the STREAMS package could not determine
the precise reason for the failure. The error could be anything from a
physical device error to an attempt to use an invalid stream handle.
10.1.4. The End-of-Stream Return ($eos)
The precise meaning of “end-of-stream”
($eos error) depends on the
stream type, on whether the requested operations was input or output,
and on the underlying implementation. The distinction between a normal
$error and $eos might possibly be
of some use to a program. When in
doubt, treat $eos and $error the same way.
For TTY streams, in the input direction, $eos means that the user typed some system-dependent key combination to signal the end of an exchange (e.g., CTRL-D under BSD UNIX). Repeated $eos errors, however, might mean that no more input is available at all.
For socket streams, in both the input and output directions, $eos means that the process at the other end has “hung up” the connection for some reason.
For some implementations of some stream types,
such as standard UNIX V.0
TTY streams, the STREAMS package may not be able to distinguish
end-of-stream from a simple lack of data. On
such platforms, the $eos return does not occur.
10.1.5. Timeout Return ($timedOut)
A return of $timedOut indicates
that the I/O operation did not occur
because the timeout value was exceeded.
This error does not occur
if a timeout value of $block (default) was supplied.
10.2. Octets
The term “octets” refers to eight-bit character units or their
contents.
The term differs from “characters” or “character units” in that
octets are uninterpreted and untranslated;
i.e., the stream operations on “characters” interpret
their arguments or return values as text, whereas “octet”
operations work on “raw bits”.
All physical channels on which stream communication is based
transmit information in the form of eight-bit units, so the
octet is the quantum of information used by most stream
I/O PROCEDUREs.
10.3. Input: $readStream
Figure 10–3. $readStream (GENERIC)
| LONG INTEGER PROCEDURE $readStream (POINTER($stream) st; PRODUCES STRING s; OPTIONAL BITS ctrlBits; OPTIONAL LONG INTEGER timeout); LONG INTEGER PROCEDURE $readStream (POINTER($stream) st; CHARADR ca; LONG INTEGER bufSize; OPTIONAL BITS ctrlBits; OPTIONAL LONG INTEGER timeout); LONG INTEGER PROCEDURE $readStream (POINTER($stream) st; ADDRESS a; LONG INTEGER bufSize; OPTIONAL BITS ctrlBits; OPTIONAL LONG INTEGER timeout); |
$readStream reads octets from the stream st into the destination STRING or buffer with maximum size given by bufSize.
The interpretation of the octets read from the stream (how they are packed into memory) depends on the the form of $readStream that is used. The STRING and CHARADR forms read text ($text mode), the CHARADR form with the $octet bit set reads octets, and the ADDRESS form reads octets into complete storage units ($image mode).
It is not necessary to specify the bits $text or $image in ctrlBits because they are implied by the GENERIC instance. However, when reading octets it is necessary to include the $octet bit, since octets are addressed by CHARADRs.
The precise interpretation of the octets in the stream is as follows:
At most one of the following buffering bits may be set:
The buffering modes and defaults for each type of object read are summarized in Table 10–4.
| Buffering Mode | $text | $octet | $image |
|---|---|---|---|
| $unbuffered | D | D | D |
| $line | X | - | - |
| $fillBuffer | X | X | X |
| $packet | X | X | X |
| (X = valid, - = invalid, D = Default) | |||
If the read is successful, the number of characters or octets actually read is returned. Otherwise, a negative error value is returned.
On streams that buffer output and that are opened for both input and output, the output is flushed with $flushStream (see below) before a read on the stream. This ensures that prompts or requests to a user or another process are sent out to the other side before the read blocks waiting for a response.
The MAINSAIL PROCEDURE ttyRead acts similarly to the following stream calls:
$readStream($tty,tempString,$line);
read(tempString,resultString);
The second call to read removes the eol that $readStream returns as part of the line.
Additional conventions applicable to $readStream are described
in Section 10.1.
10.4. Output: $writeStream
Figure 10–5. $writeStream (GENERIC)
| LONG INTEGER PROCEDURE $writeStream (POINTER($stream) st; STRING s; OPTIONAL BITS ctrlBits; OPTIONAL LONG INTEGER timeout); LONG INTEGER PROCEDURE $writeStream (POINTER($stream) st; CHARADR ca; LONG INTEGER bufSize; OPTIONAL BITS ctrlBits; OPTIONAL LONG INTEGER timeout); LONG INTEGER PROCEDURE $writeStream (POINTER($stream) st; ADDRESS a; LONG INTEGER bufSize; OPTIONAL BITS ctrlBits; OPTIONAL LONG INTEGER timeout); |
$writeStream writes the data contained in the specified buffer to the stream st.
The interpretation of the buffer (how it is converted into octets) depends on the the form of $writeStream that is used. The STRING and CHARADR (without $octet set) forms write text by translating it to the PDF character set (if necessary), the CHARADR form with $octet set in ctrlBits writes octets directly, and the ADDRESS form writes storage units by converting them to octets in the standard way for the host system. The bufSize parameter is in character units for the CHARADR form and storage units for the ADDRESS form.
It is not necessary to specify the bits $text or $image in ctrlBits because they are implied by the GENERIC instance. However, when writing octets it is necessary to include the $octet bit because octets are addressed by CHARADRs.
At most one of the following buffering bits may be set:
$writeStream returns a nonnegative LONG INTEGER on a successful write. Otherwise, a negative value is returned.
The system PROCEDURE ttyWrite produces results similar to:
$writeStream($tty,argStr,$line)
Additional conventions applicable to $writeStream are described
in Section 10.1. Figure 10–6. $cReadStream and $cWriteStream
10.5. Single-Character I/O: $cReadStream and $cWriteStream
INTEGER
PROCEDURE $cReadStream
(POINTER($stream) st;
OPTIONAL BITS ctrlBits;
OPTIONAL LONG INTEGER timeout);
LONG INTEGER
PROCEDURE $cWriteStream
(POINTER($stream) st;
INTEGER c;
OPTIONAL BITS ctrlBits;
OPTIONAL LONG INTEGER timeout);
The PROCEDUREs $cReadStream and $cWriteStream are similar to $readStream and $writeStream except that they read and write single characters or octets at a time. It is necessary to include the $text or $octet bit to indicate whether characters or octets should be read or written.
The following bits are valid in ctrlBits:
On success, $cReadStream returns the actual octet or character value. On failure it returns one of the standard error codes $error, $eos, or $timedOut, except that the value is converted to an INTEGER instead of a LONG INTEGER (i.e., test for cvi($error), cvi($eos), or cvi($timedOut)). $cReadStream is the only stream I/O PROCEDURE that returns an INTEGER instead of a LONG INTEGER.
On success, $cWriteStream returns an arbitrary nonnegative value; on failure, it returns a negative value.
The buffer PROCEDUREs $readStream and $writeStream are more efficient for reading many characters or octets. However, the character versions of these PROCEDUREs are more convenient when program logic requires reading a single character or octet at a time.
Additional conventions applicable to
$cReadStream and $cWriteStream
are described in Section 10.1. Figure 10–7. $flushStream and $clearStream
10.6. Miscellaneous Operations:
$flushStream and $clearStream
BOOLEAN
PROCEDURE $flushStream
(POINTER($stream) st;
OPTIONAL BITS ctrlBits);
BOOLEAN
PROCEDURE $clearStream
(POINTER($stream) st;
BITS ctrlBits);
$flushStream forces all output done to the stream out so that it is available to the process or device at the other end. This action is of use if the implementation of the stream uses an internal buffer for efficiency. A read on the stream automatically causes the previously buffered output to be sent, but a program might want to ensure that all output has been sent before issuing an error message, for example.
$clearStream discards pending input (if input is set in ctrlBits) and/or output (if output is set in ctrlBits) on st. For example, if an editor reads an invalid command character from the terminal and prints an error message, it would be reasonable to call $clearStream($tty,input) so that all unread characters typed ahead by the user are discarded (since the user is likely to assume that the errant command was performed).
Both $flushStream and $clearStream return TRUE
if the operation was
successful and FALSE
if the operation failed and errorOK was specified
in ctrlBits.
If errorOK was not set, they issue a fatal error.
10.7. Constants and Macros for Stream I/O
The following constants are provided
to aid in writing portable MAINSAIL
programs that manipulate streams:
Similarly, when two streams write to the same scheduled stream, it is not specified which write occurs first, or whether one stream's write is more likely to succeed after the other stream's write has been performed.
MAINSAIL STREAMS User's Guide, Chapter 10