Part I Application Programming Interface
How STREAMS Works--Application Interface
How STREAMS Works at the Kernel Level
Structure of a STREAMS Device Driver
Configuring Multiplexed Streams
2. STREAMS Application-Level Components
3. STREAMS Application-Level Mechanisms
4. Application Access to the STREAMS Driver and Module Interfaces
7. STREAMS Framework - Kernel Level
8. STREAMS Kernel-Level Mechanisms
11. Configuring STREAMS Drivers and Modules
14. Debugging STREAMS-based Applications
B. Kernel Utility Interface Summary
The capitalized word “STREAMS” refers to the STREAMS programming model and facilities. The word “stream” refers to an instance of a full-duplex path using the model and facilities between a user application and a driver.
A stream is a data path that passes data in both directions between a STREAMS driver in kernel space, and a process in user space. An application creates a stream by opening a STREAMS device (see Figure 1-1).
A stream head is the end of the stream nearest the user process. It is the interface between the stream and the user process. When a STREAMS device is first opened, the stream consists of only a stream head and a STREAMS driver.
A STREAMS module is a defined set of kernel-level routines and data structures. A module does “black-box” processing on data that passes through it. For example, a module converts lowercase characters to uppercase, or adds network routing information. A STREAMS module is dynamically pushed on the stream from the user level by an application. Full details on modules and their operation are covered in Chapter 10, STREAMS Modules.
A STREAMS device driver is a character device driver that implements the STREAMS interface. A STREAMS device driver exists below the stream head and any modules. It can act on an external I/O device, or it can be an internal software driver, called a pseudo-device driver. The driver transfers data between the kernel and the device. The interfaces between the driver and kernel are known collectively as the Solaris operating environment Device Driver Interface/Driver Kernel Interface (Solaris operating environment DDI/DKI). The relationship between the driver and the rest of the UNIX kernel is explained in Writing Device Drivers. Details of device drivers are explained in Chapter 9, STREAMS Drivers.
Data on a stream is passed in the form of messages. Messages are the means by which all I/O is done under STREAMS. Each stream head, STREAMS module, and driver has a read sideand a write side. When messages go from one module's read side to the next module's read side, they are said to be traveling upstream. Messages passing from one module's write side to the next module's write side are said to be traveling downstream. Kernel-level operation of messages is discussed in Message Components.
Each stream head, driver, and module has its own pair of queues, one queue for the read side and one queue for the write side. Messages are ordered into queues, generally on a first-in, first-out basis (FIFO), according to priorities associated with them. Kernel-level details of queues are covered in Structure of a Message Queue.
Figure 1-2 Messages Passing Using Queues
To communicate with a STREAMS device, an application's process uses read(2), write(2), getmsg(2), getpmsg(2), putmsg(2), putpmsg(2), and ioctl(2) to transmit or receive data on a stream.
From the command line, configure a stream with autopush(1M). From within an application, configure a stream with ioctl(2) as described in streamio(7I).
The ioctl(2) interface performs control operations on and through device drivers that cannot be done through the read(2) and write(2) interfaces. ioctl(2) operations include pushing and popping modules on and off the stream, flushing the stream, and manipulating signals and options. Certain ioctl(2) commands for STREAMS operate on the whole stream, not just the module or driver. The streamio(7I) manual page describes STREAMS ioctl(2) commands. Chapter 4, Application Access to the STREAMS Driver and Module Interfaces details interstream communications.
The modularity of STREAMS allows one or more upper streams to route data into one or more lower streams. This process is defined as multiplexing (mux). Example configurations of multiplexers are described in Configuring Multiplexed Streams.
Polling within STREAMS enables a user process to detect events occurring at the stream head, specifying the event to look for and the amount of time to wait for it to happen. An application might need to interact with multiple streams. The poll(2) system call enables applications to detect events that occur at the head of one or more streams. Chapter 3, STREAMS Application-Level Mechanisms describes polling.
Flow control regulates the rate of message transfer between the user process, stream head, modules, and driver. With flow control, a module that cannot process data at the rate being sent can queue the data to avoid flooding modules upstream. Flow control is local to each module or driver, and is voluntary. Chapter 8, STREAMS Kernel-Level Mechanisms describes flow control.