previous next top contents index framed top this page unframed
3.1. Stream Features
3.1.1. Summary of Stream Support and Implementation
Figure 3–1
is a Venn diagram showing the possible support
combinations for various stream-related features. Basic STREAMS,
guaranteed for all STREAMS implementations, includes only the
basic TTY (terminal)
stream, which may be limited to half-duplex line-at-a-time
operation. Various additional features of the TTY stream are
available on some platforms (see below).
On some platforms, advanced STREAMS provides the ability to control processes and communicate with other processes using server/client communication. If advanced STREAMS is supported, the ability to schedule advanced STREAMS may also be supported.
Appendix C summarizes the current status of support and implementation of STREAMS on the current MAINSAIL platforms. Programs that must run on systems where only some STREAMS features are supported must use the runtime tests provided to determine which features are available. They must then adapt to the environment as best they can.
POINTER($stream) $tty;
is automatically opened to the controlling terminal.
The TTY stream may be half-duplex, in which case I/O may be restricted to a line at a time. This minimal implementation is sufficient to write, e.g., a KERMIT server, but not a KERMIT client. The minimal STREAMS capabilities provided for half-duplex TTY streams are no more than what the MAINSAIL language currently guarantees for terminal I/O on half-duplex systems.
The minimal STREAMS capabilities
for full-duplex TTY streams are more than
what MAINSAIL terminal I/O promises, but similar to
what the full-duplex MAINSAIL display MODULEs assume.
Thus, full-duplex
TTY streams can be used to read and write
single characters at a time or
groups of characters, optionally with echo turned off.
3.1.3. Reading Interrupt Characters from the TTY
On some platforms,
the TTY stream may support the ability to read all interrupt
and flow control characters as normal characters so that a terminal
emulator can be written. This mode is controlled by bits passed to
$readStream.
Refer to Chapter 11 for a description of these
bits.
3.1.4. Opening Serial TTY Lines
The basic TTY stream, $tty,
is pre-opened by the STREAMS package and is
connected to the “primary” input/output device, usually an
interactive terminal.
The ability to open additional serial TTY lines by
name is supported on many systems. The program must provide
an installation-dependent name that corresponds to the desired serial
line (see Chapter 11).
3.1.5. Setting the Baud Rate on TTY Streams
The ability to set the baud rate on TTY streams is supported on some
systems.
If this capability is not supported, the PROCEDUREs used to
set and get the baud rate ($setBaudRate and $getBaudRate;
see Section 11.4)
give error returns.
3.1.6. Writing a BREAK on TTY Streams
STREAMS supports
the ability to write a BREAK (something like a sustained NUL;
often interpreted by programs as an interrupt or closed connection)
on TTY streams
on some systems using the PROCEDURE $writeStreamBreak
(see Section 11.4).
The PROCEDURE gives an error return if the capability is not
supported.
3.1.7. Clearing Pending I/O
The ability to clear pending input and/or output is supported on some
systems using the PROCEDURE $clearStream
(described in Section 10.6).
The PROCEDURE gives an error return if the capability is not
supported.
3.1.8. Scheduling of TTY Streams
TTY streams may support scheduled I/O so that more than
one coroutine doing TTY I/O may run at once (see below).
A program may determine whether scheduling applies to the TTY
stream on the
host system, that is, whether $tty can participate in scheduled I/O
activities along with other streams, by the test
$isScheduled($tty).
If not, I/O to $tty must be assumed to block.
3.1.9. Catching Keyboard Interrupts
The TTY stream may support the ability to intercept and test
a single keyboard interrupt character (CTRL-C on many systems).
A program may
determine whether catching TTY keyboard interrupts is possible on its
$tty by calling the $enableInterrupts
PROCEDURE and testing its return
value.
If $enableInterrupts succeeds, the exception $keyboardInterruptExcpt is raised whenever the Scheduler gets control and discovers an interrupt that has not previously been observed. This exception is raised in the coroutine that most recently called $enableInterrupts.
If the $tty is scheduled, i.e., $isScheduled($tty) is TRUE,
the exception
$keyboardInterruptExcpt can be raised
while the program is waiting for
TTY input. Otherwise, interrupts that occur during TTY input
cause the exception to be raised the next time that the Scheduler
is invoked following the TTY input.
3.1.10. Server/Client Communication
A platform may support server/client communication through
one or more network protocols.
3.1.11. Child Process Creation
If child process creation is supported, the stream MODULE
PROCESS is available for the system.
Child processes may be categorized as either cooperating or noncooperating.
A child process that knows it is being invoked by a parent and that uses an agreed-upon communication protocol is called a cooperating child process. Typically, a cooperating child process uses its $tty for error messages and debugging and a secondary stream (available as the STREAMS system variable $parent) for communication with the parent process.
A child process that does not know that it is being run from a parent is called a noncooperating child process. All communication with noncooperating children takes place through the child's TTY.
Some systems support the ability to create noncooperating child processes with a $tty that has all of the semantics normally associated with a $tty, including echo and line editing on input. On such systems the stream MODULE called PTYPRO is available.
Limits on the ability to run noncooperating general child processes
through PTYPRO are system-dependent.
On some systems, the PTYPRO
stream is half-duplex, capable only of line-at-a-time I/O. The
results of running a display editor in such a child process would be
less than satisfactory!
3.1.12. The System Shell as a Child Process
The ability to run the standard system shell
(command interpreter) through PTYPRO is
system-dependent. Even if the system supports the concept of a
“shell”, the results of running it may be less than satisfactory for
some applications.
3.1.13. Scheduling of Advanced STREAMS
Scheduling of advanced STREAMS is
available on some platforms. Without scheduling,
the functionality of advanced STREAMS is limited because multiple I/O
tasks cannot be performed simultaneously. Without scheduling,
for example, servers can process only one client at a time and they
can accept clients using only one network protocol.
The STREAMS system macro $systemSupportsScheduling tells whether the host system supports scheduling of advanced STREAMS. This support is independent of whether the system supports scheduling on TTY streams. Thus, there are four possible levels of scheduling possible on a given system:
IF $systemSupportsScheduling AND $isScheduled($tty) THEN
# the system supports scheduling on all streams
EF $systemSupportsScheduling AND NOT $isScheduled($tty) THEN
# the system supports scheduling of advanced STREAMS but
# not $tty
EF $isScheduled($tty) AND NOT $systemSupportsScheduling THEN
# the system supports scheduling of only $tty
EL # the system does not support scheduling at all
The STREAMS system macro $systemSupportsTimeout tells whether the host system supports the ability to use timeouts on scheduled streams. If the TTY can be scheduled and $systemSupportsTimeout is TRUE, timed input may also be performed on the TTY. If $systemSupportsTimeout is FALSE, timeout values are ignored.
Currently, all systems that support scheduled streams also support
timeouts.
The types of streams currently known to the system are:
TTY streams allow the program to communicate with a terminal. The
terminal may be either a screen and a keyboard or a serial line
(e.g., RS-232).
For historical reasons that are not likely to change soon, TTY
streams have special modes, limitations, and job control side effects.
Socket streams provide conceptually simple, unencumbered communication
between processes.
Memory streams are a special kind of stream for internal communication
between coroutines of the same process. They are created in pairs.
PTY streams are used to communicate with a child process that thinks it
is communicating with a real terminal. The parent, which is typically a
shell or a windowing system, passes on the child's output, read from the
PTY, to a terminal or window. The parent passes keystrokes to the child
by writing to the PTY.
Other stream types may be implemented in the future.
3.2. Stream Types
The basic stream I/O PROCEDUREs work uniformly regardless of the
underlying stream device being used. Some stream types, most notably
TTY streams, require special additional
PROCEDUREs and have limitations
specific to the device.
These limitations must usually be understood by the
programmer in order to use these devices effectively,
except in simple cases.
3.3. Automatic Scheduling of Stream I/O
Task scheduling is crucial to distributed computing, since it allows a
single process to interact with several other processes (and possibly
also a user) without constraining the order in which the communications
take place. The power of stream I/O for multiprocessing and multitasking
lies in a special STREAMS system coroutine called the Scheduler.
Whenever any coroutine calls a stream I/O PROCEDURE, the Scheduler coroutine is resumed to decide what to do next. The original caller coroutine is resumed by the Scheduler only when its requested I/O is ready, i.e., when the I/O can be performed without blocking. In this way, the program runs much the way it would if each of its coroutines were run as a separate process under a multiprocess operating system, or as separate programs on two different computers.
Chapter 8 describes the use of stream scheduling for
implementing multitasking programs.
In the current release of MAINSAIL, the stream I/O facilities are
“loosely coupled” with the MAINSAIL runtime system. In
particular, unless special steps are taken, normal TTY I/O through
cmdFile and logFile, the file TTY,
ttyRead and ttyWrite,
and $timeout are
performed independently of the stream Scheduler and therefore block.
Eventually it may be that all I/O to the file TTY
(e.g., the default
cmdFile and logFile) will go through the $tty stream,
at least on systems where STREAMS is installed.
The
PROCEDUREs ttyRead, ttyWrite,
and ttycWrite may also eventually go
through the $tty stream.
Should this “strong coupling” be implemented,
the PROCEDURE $timeout will work through the Scheduler if
$systemSupportsTimeout is TRUE.
In the meantime, to aid programs that wish to make output to
the file TTY be scheduled,
the device MODULE NTTY is supplied.
Output to a file opened through NTTY goes through $tty.
In particular,
if cmdFile and logFile are reopened through NTTY,
any I/O to the terminal
through them is scheduled, including error messages reported
by errMsg.
Example 3–2 shows how a program can arrange to use the NTTY
device MODULE in place of the file TTY.
Example 3–2. Using the NTTY Device MODULE
3.4. Loose Coupling of STREAMS to MAINSAIL
RESTOREFROM "strHdr";
POINTER(textFile) origCmdFile,newCmdFile,origLogFile,
newLogFile;
INLINE PROCEDURE startup;
BEGIN
# Make cmdFile/logFile go through ntty>
enterLogicalName("tty","ntty" & $devModBrkStr);
setModName("tty","ntty");
origCmdFile := cmdFile;
origLogFile := logFile;
open(newCmdFile,"ntty" & $devModBrkStr,input);
open(newLogFile,"ntty" & $devModBrkStr,output);
cmdFile := newCmdFile; close(origCmdFile);
logFile := newLogFile; close(origLogFile);
END;
INLINE PROCEDURE cleanup;
BEGIN
# Restore original cmdFile/logFile
enterLogicalName("tty","");
setModName("tty","");
close(cmdFile); # Reopens to TTY
newLogFile := logFile;
open(origLogFile,"tty",output);
logFile := origLogFile;
close(newLogFile);
END;
INITIAL PROCEDURE;
BEGIN
$initializeStreams;
startup;
...
END;
FINAL PROCEDURE;
cleanup;
MAINSAIL STREAMS User's Guide, Chapter 3