streams(7) streams(7)
NAME
streams - ioctl interface
DESCRIPTION
Streams is a mechanism that is used in the UNIX® kernel for
some device drivers. These drivers are usually for
communications or tty type applications. To most programs,
this interface is, with a few exceptions, the same as that
of traditional UNIX character devices. When used with a
streams line-discipline this interface is the same as that
of normal UNIX terminals.
The version of streams implemented under UNIX V.2.1 is a
fuctional subset of that provided by later UNIX
implementations. It is upwardly compatible with such
systems.
The main difference between streams and other character
device drivers is that the streams interface is message
based. Commands and data exchanged between devices,
processes and line disciplines (streams modules) are sent in
messages. A number of special ioctl functions have been
defined to send and receive these messages.
A stream is built by opening a stream style device (the
ability of a device to ``stream'' is defined by the writer
of the device's device-driver, either a device streams or it
doesn't). When the device is open it consists of the device
and the ``stream head,'' the interface to the process that
opened the device.
The device and the stream head can communicate by means of
messages across the full-duplex stream. Processes can
communicate with the stream head by means of system calls
such as read(2), write(2) and ioctl(2).
Using the IPUSH, a stream module can be pushed (in a LIFO
or stacked manner) onto the stream. More than one stream
module can be pushed onto such a stream at a time. The
module closest to the stream head may be removed using the
IPOP ioctl call.
Closing a stream causes the modules to be popped from the
stream, the device to be closed, and the stream dismantled.
Modules exist in the kernel and are referenced by name.
There are two standard streams modules:
line A tty style line discipline. When pushed, it
implements all the functionality described by
termio(7). Most terminal-style communications
lines use this module.
Page 1 (last mod. 1/15/87)
streams(7) streams(7)
shlr The shell layering module. shlr responds to shell
layering ioctls to implement shell layering on
stream based ttys. Normally shl(1) is the only
utility that uses this module.
The streams system implements a number of ioctls, all of the
ioctls described in termio(7) are provided for
compatability. Some devices and/or modules may not respond
to these calls. In particular many of the line discipline
related ioctls will either fail or be ignored unless the
module line has been pushed onto the stream. In addition
the following streams related ioctls are supported, they are
defined in the include file <sys/stropts.h>.
ISTR ioctl(fd, I_STR, &strioctl)
struct strioctl strioctl;
This ioctl builds an ioctl packet and sends it
down the stream. It may be interpreted by any
module on the stream or by the device at the end.
The packet is returned with data and an indication
of success or failure. The data structure
strioctl is used to describe the packet to be
sent. It has 4 fields:
iccmd The command to be sent
ictimout How long to wait for the ioctl to
succeed before failing (in seconds),
values 0 and -1 have special meanings, 0
means wait for the system default time,
-1 means wait forever.
icdp Points to the address of the data to be
sent down the stream, or the address at
which data returned from the stream is
to be stored.
iclen Is the length of the data to be sent, in
bytes, or the size of the buffer into
which returned data is to be stored.
Errors:
EFAULT if ic_dp references an invalid address.
Any other device/module specific error message.
INREAD nmess = ioctl(fd, INREAD, &first);
INREAD returns the number of messages in the
queue at the streams head as its result. It also
returns the number of bytes in the first message
Page 2 (last mod. 1/15/87)
streams(7) streams(7)
in the queue to the address referenced by its
argument.
Errors:
EFAULT if the argument references an invalid
address.
IPUSH ioctl(fd, I_PUSH, module)
char *module;
This ioctl pushes the streams module named by the
null terminated string module onto an open stream.
Errors:
EFAULT if the module name references an invalid
address. EINVAL if the module name does not
describe an existing streams module in the Oreo
kernel.
Any other error the streams module might return if
it decides not to allow the push.
IPOP ioctl(fd, I_POP, 0)
The ioctl removes the streams module closest to
the process on the stream.
Errors:
EINVAL if no such module exists
ILOOK ioctl(fd, I_LOOK, buff)
char buff[FMNAMESZ+1];
This returns the name of the streams module
closest to the process on a stream.
Errors:
EFAULT if the buffer for the name is located at an
invalid address.
EINVAL if there are no modules pushed onto the
stream.
IFLUSH ioctl(fd, I_FLUSH, flushtype)
This generates a message that is sent down the
queue to flush messages waiting at modules down
the stream. The parameter can be one of three
allowed values:
FLUSHR flush messages coming down the stream
towards the process
Page 3 (last mod. 1/15/87)
streams(7) streams(7)
FLUSHW flush messages moving up the stream away
from the process
FLUSHRW flush all messages in the stream
Errors:
EINVAL the parameter is not one of the
above values
EAGAIN insufficient resources are
available to send the message up the
queue and it should be retried at a
later time.
ISRDOPT ioctl(fd, I_SRDOPT, srdtype)
This ioctl changes the manner in which the stream
head treats incoming messages as they are passed
to a process as part of a read(2) system call.
The parameter can take one of three possible
values:
RNORM in stream mode - messages are read from
the stream and message boundaries are
ignored (except for 0 length messages
which are always returned as separate
messages and are normally treated as end
of file markers)
RMSGN a read terminates at either the end of
the message or when the read buffer is
full. Any message data remaining is
available from future reads.
RMSGD a read terminates when either the end of
the message is found or the read buffer
is full. Any unread data is discarded.
When a stream is first opened it has the
default operating mode of RNORM. It is
also possible for upstream modules to
change this.
Errors:
EINVAL the parameter is not one of the
above values
IGRDOPT ioctl(fd, I_GRDOPT, &opt)
int opt;
This call returns the current read option (as
specified above under ISRDOPT).
Page 4 (last mod. 1/15/87)
streams(7) streams(7)
Errors:
EFAULT if the argument is a valid address
IFIND find = ioctl(fd, I_FIND, buff)
char buff[FMNAMESZ+1];
This call returns 1 if a module of the name given
in the null terminated string passed in the
argument is present in the stream. Or 0 if the
module does not exist.
Errors:
EINVAL if the name is not the name of a module in
the kernel.
EFAULT if the address of the name passed as the
argument is not valid.
IMNAME ioctl(fd, I_MNAME, &par)
union {
int depth;
char buff[FMNAMESZ+1];
} par;
This ioctl returns the name of the module or
driver at the depth on the stream specified by the
parameter. The stream head is at depth 0. The last
module found on the stream will be the driver.
Note: this ioctl is not necessarily provided on
all systems that provide a stream interface. It
should not be used if program portability is a
factor.
Errors:
EFAULT if the address of the parameter is invalid
EINVAL if the depth is less than 0 or references a
module past the driver at the end of the stream
Terminal Lines
When using a stream based terminal it is usually necessary
to push a line discipline module onto the stream before use.
In almost all cases this is done by /etc/getty or /etc/init
when you log onto your system. When you are opening an
unused terminal line it may then be required. Pushing more
than one line discipline onto a stream should be avoided as
the results are undefined and will not be useful. Two
methods are provided to make pushing line disciplines
easier. They both can be used on non stream based character
drivers without any undue effect and they will avoid the
multipl pushing of line disciplines if one is already
pushed.
Page 5 (last mod. 1/15/87)
streams(7) streams(7)
linepush(3) is a library routine that is passed the file
descriptor of and open device (from open(2)). It will push
a line discipline onto the device if it is a streaming
device and there is not one pushed already.
/etc/linesane(1M) is a utility that can be run from shell
scripts (such as those started from /etc/inittab(4)) it
takes one parameter, an integer representing an open file
descriptor on which the line discipline is to be pushed. It
behaves similarily to linepush(3) above.
Further Functionality
The following extensions are provided to the streams system.
They are not necessarily provided with other streams
implementations and should not be used if portability is
important.
select(2) allows a process to wait for input from more
than one open device, socket or stream
FIONBIO allows a process to make non blocking reads
to a stream (see termio(7))
FIONASYNC sends a SIGIO signal to a process when input
is available from the queue (see termio(7))
FIONREAD returns the number of characters available to
be read from the stream head (this is
different from INREAD above) (see termio(7))
SEE ALSO
line_sane(1M). open(2), close(2), read(2), write(2),
ioctl(2), select(2), line_push(3).
Page 6 (last mod. 1/15/87)