Skip Navigation Links | |
Exit Print View | |
STREAMS Programming Guide Oracle Solaris 11.1 Information Library |
Part I Application Programming Interface
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 message types found in sys/stream.h are described in this appendix, classified according to their message queueing priority. Ordinary messages are described first, with high-priority messages following. In certain cases, two message types may perform similar functions, differing only in priority. Message construction is described in Chapter 3, STREAMS Application-Level Mechanisms. The use of the word module generally implies module or driver.
Ordinary messages are also called normal or nonpriority messages. Ordinary messages are subject to flow control whereas high-priority messages are not.
Sent to a driver to request that BREAK be transmitted on whatever media the driver is controlling.
The message format is not defined by STREAMS and its use is developer dependent. This message may be considered a special case of an M_CTL message. An M_BREAK message cannot be generated by a user-level process and is always discarded if passed to the stream head.
Generated by modules that send information to a particular module or type of module. M_CTL messages are typically used for intermodule communication, as when adjacent STREAMS protocol modules negotiate the terms of their interface. An M_CTL message cannot be generated by a user-level process and is always discarded if passed to the stream head.
Contains ordinary data. Messages allocated by allocb(9F) are M_DATA type by default. M_DATA messages are generally sent bidirectionally on a stream and their contents can be passed between a process and the stream head. In the getmsg(2) and putmsg(2) system calls, the contents of M_DATA message blocks are referred to as the data part. Messages composed of multiple message blocks typically have M_DATA as the message type for all message blocks following the first.
Sent to a media driver to request a real-time delay on output. The data buffer associated with this message is expected to contain an integer to indicate the number of machine cycles of delay desired. M_DELAY messages are typically used to prevent transmitted data from exceeding the buffering capacity of slower terminals.
The message format is not defined by STREAMS and its use is developer dependent. Not all media drivers may understand this message. This message may be considered a special case of an M_CTL message. An M_DELAY message cannot be generated by a user-level process and is always discarded if passed to the stream head.
Generated by the stream head in response to I_STR, I_LINK, I_UNLINK, I_PLINK, and I_PUNLINK ioctls (see streamio(7I)). This message is also generated in response to ioctl calls that contain a command argument value not defined in streamio(7I). When one of these ioctl(2) is received from a user process, the stream head uses values supplied in the call and values from the process to create an M_IOCTL message containing them, then sends the message downstream. M_IOCTL messages perform the general ioctl(2) functions of character device drivers.
For an I_STR ioctl(2), the user values are supplied in a structure of the following form, provided as an argument to the ioctl(2) call (see I_STR in streamio(7I)):
struct strioctl { int ic_cmd; /* downstream request */ int ic_timout; /* ACK/NAK timeout */ int ic_len; /* length of data arg */ char *ic_dp; /* ptr to data arg */ };
where ic_cmd is the request (or command) defined by a downstream module or driver, ic_timout is the time the stream head waits for acknowledgement to the M_IOCTL message before timing out, and ic_dp points to an optional data buffer. On input, ic_len contains the length of the data in the buffer that was passed in. On return from the call, it contains the length of the data, if any, being returned to the user in the same buffer.
The M_IOCTL message format is one M_IOCTL message block followed by zero or more M_DATA message blocks. STREAMS constructs an M_IOCTL message block by placing an iocblk(9S) structure, defined in <sys/stream.h>, in its data buffer. The iocblk(9S) structure differs for 64–bit and 32–bit architectures.
#if defined(_LP64) struct iocblk { int ioc_cmd; /* ioctl command type */ cred_t *ioc_cr; /* full credentials */ uint ioc_id; /* ioctl id */ uint ioc_flag; /* see below */ size_t ioc_count; /* count of bytes in data field */ int ioc_rval; /* return value */ int ioc_error; /* error code */ }; #else struct iocblk { int ioc_cmd; /* ioctl command type */ cred_t *ioc_cr; /* full credentials */ uint ioc_id; /* ioctl id */ size_t ioc_count; /* count of bytes in data field */ int ioc_error; /* error code */ int ioc_rval; /* return value */ intt ioc_fill1; uint ioc_flag; /* see below */ int ioc_filler[2]; /* reserved for future use */ }; #endif /* _LP64 */
For an I_STR ioctl(2), ioc_cmd corresponds to ic_cmd of the strioctl structure. ioc_cr points to a credentials structure defining the user process's permissions (see cred.hfile).. Its contents can be tested to determine whether the user issuing the ioctl(2) call is authorized to do so. For an I_STR ioctl(2), ioc_count is the number of data bytes, if any, contained in the message and corresponds to ic_len.
ioc_id is an identifier generated internally, and is used by the stream head to match each M_IOCTL message sent downstream with response messages sent upstream to the stream head. The response message that completes the stream-head processing for the ioctl(2) is an M_IOCACK (positive acknowledgement) or an M_IOCNAK (negative acknowledgement) message.
For an I_STR ioctl(2), if a user supplies data to be sent downstream, the stream head copies the data (pointed to by ic_dp in the strioctl structure) into M_DATA message blocks and links the blocks to the initial M_IOCTL message block. ioc_count is copied from ic_len. If there are no data, ioc_count is zero.
If the stream head does not recognize the command argument of an ioctl(2), the head creates a transparent M_IOCTL message. The format of a transparent M_IOCTL message is one M_IOCTL message block followed by one M_DATA block. The form of the iocblk structure is the same as above. However, ioc_cmd is set to the value of the command argument in the ioctl(2) and ioc_count is set to TRANSPARENT, defined in <sys/stream.h>. TRANSPARENT distinguishes the case where an I_STR ioctl(2) specifies a value of ioc_cmd equivalent to the command argument of a transparent ioctl(2). The M_DATA block of the message contains the value of the arg parameter in the ioctl(2).
The first module or driver that understands the ioc_cmd request contained in the M_IOCTL acts on it. For an I_STR ioctl(2), this action generally includes an immediate upstream transmission of an M_IOCACK message. For transparent M_IOCTLs, this action generally includes the upstream transmission of an M_COPYIN or M_COPYOUT message.
Intermediate modules that do not recognize a particular request must pass the message on. If a driver does not recognize the request, or the receiving module can not acknowledge it, an M_IOCNAK message must be returned.
M_IOCACK and M_IOCNAK message types have the same format as an M_IOCTL message and contain an iocblk structure in the first block. An M_IOCACK block may be linked to following M_DATA blocks. If one of these messages reaches the stream head with an identifier that does not match that of the currently outstanding M_IOCTL message, the response message is discarded. A common means of ensuring that the correct identifier is returned is for the replying module to convert the M_IOCTL message into the appropriate response type and set ioc_count to 0 if no data is returned. Then, qreply(9F) is used to send the response to the stream head.
In an M_IOCACK or M_IOCNAK message, ioc_error holds any return error condition set by a downstream module. If this value is non-zero, it is returned to the user in errno. Note that both an M_IOCNAK and an M_IOCACK can return an error. However, only an M_IOCACK can have a return value. For an M_IOCACK, ioc_rval holds any return value set by a responding module. For an M_IOCNAK, ioc_rval is ignored by the stream head.
If a module processing an I_STR ioctl(2) is sending data to a user process, it must use the M_IOCACK message that it constructs such that the M_IOCACK block is linked to one or more following M_DATA blocks containing the user data. The module must set ioc_count to the number of data bytes sent. The stream head places the data in the address pointed to by ic_dp in the user I_STR strioctl structure.
A module processing a transparent ioctl(2) that is sending data to a user process can use only an M_COPYOUT message. For a transparent ioctl(2), no data can be sent to the user process in an M_IOCACK message. All data must be sent in a preceding M_COPYOUT message. The stream head ignores any data contained in an M_IOCACK message (in M_DATA blocks) and frees the blocks.
No data can be sent with an M_IOCNAK message for any type of M_IOCTL. The stream head ignores and frees any M_DATA blocks.
The stream head blocks the user process until an M_IOCACK or M_IOCNAK response to the M_IOCTL (same ioc_id) is received. For an M_IOCTL generated from an I_STR ioctl(2), the stream head times out if no response is received in ic_timout interval (the user can specify an explicit interval or specify use of the default interval). For M_IOCTL messages generated from all other ioctl(2)s, the default (infinite) is used.
The M_PASSFP message passes a file pointer from the stream head at one end of a stream pipe to the stream head at the other end of the same stream pipe.
The message is generated as a result of an I_SENDFD ioctl(2) (see streamio(7I)) issued by a process to the sending stream head. STREAMS places the M_PASSFP message directly on the destination stream head's read queue to be retrieved by an _RECVFD ioctl(2) (see streamio(7I)). The message is placed without passing it through the stream (that is, it is not seen by any modules or drivers in the stream). This message should never be present on any queue except the read queue of a stream head. Consequently, modules and drivers do not need to recognize this message, and it can be ignored by module and driver developers.
The M_PROTO message contains control information and associated data. The message format is one or more M_PROTO message blocks followed by zero or more M_DATA message blocks. The semantics of the M_DATA and M_PROTO message blocks are determined by the STREAMS module that receives the message.
Note - On the write side, the user can only generate M_PROTO messages containing one M_PROTO message block.
The M_PROTO message block typically contains implementation dependent control information. M_PROTO messages are generally sent bidirectionally on a stream, and their contents can be passed between a process and the stream head. The contents of the first message block of an M_PROTO message is generally referred to as the control part, and the contents of any following M_DATA message blocks are referred to as the data part. In the getmsg(2) and putmsg(2), the control and data parts are passed separately.
The format of M_PROTO and M_PCPROTO (generically PROTO) messages sent upstream to the stream head allows multiple PROTO blocks at the beginning of the message although its use is not recommended. getmsg(2)) compacts the blocks into a single control part when passing them to the user process.
This message is reserved for internal use. Modules that do not recognize this message must pass it on. Drivers that do not recognize it must free it.
This message is used to alter some characteristics of the stream head. It is generated by any downstream module, and is interpreted by the stream head. The data buffer of the message has the following structure, as defined in stream.h:
struct stroptions { uint so_flags; /* options to set */ shor so_readopt; /* read option */ ushort so_wroff; /* write offset */ ssize_t so_minpsz; /* minimum read packet size */ ssize_t so_maxpsz; /* maximum read packet size */ size_t so_hiwat; /* read queue high–water mark */ size_t so_lowat; /* read queue low–water mark */ unsigned char so_band; /* band for water marks */ ushort so_erropt; /* error option */ ssize_t so_maxblk; /* maximum message block size */ ushort so_copyopt; /* copy options (see stropts.h) */ };
where so_flags specifies which options are to be altered, and can be any combination of the following:
SO_ALL — Update all options according to the values specified in the remaining fields of the stroptions structure.
SO_READOPT — Set the read mode (see read(2)) as specified by the value of so_readopt to:
RNORM — Byte stream
RMSGD — Message discard
RMSGN — Message non-discard
RPROTNORM — Normal protocol
RPROTDAT — Turn M_PROTO and M_PCPROTO msgs into M_DATA msgs
RPROTDIS — Discard M_PROTO and M_PCPROTO blocks in a msg and retain any linked M_DATA blocks
SO_WROFF — Direct the stream head to insert an offset (unwritten area), specified by so_wroff into the first message block of all M_DATA messages created as a result of a write(2). The same offset is inserted into the first M_DATA message block, if any, of all messages created by a putmsg system call. The default offset is zero.
The offset must be less than the maximum message buffer size (system dependent). Under certain circumstances, a write offset may not be inserted. A module or driver must test that b_rptr in the msgb(9S)structure is greater than db_base in the datab(9S) structure to determine that an offset has been inserted in the first message block.
SO_MINPSZ — Change the minimum packet size value associated with the stream head read queue to so_minpsz. This value is advisory for the module immediately below the stream head. It should limit the size of M_DATA messages that the module should put to the stream head. There is no intended minimum size for other message types. The default value in the stream head is zero.
SO_MAXPSZ — Change the maximum packet size value associated with the stream head read queue to so_maxpsz. This value is advisory for the module immediately below the stream head. It should limit the size of M_DATA messages that the module should put to the stream head. There is no intended maximum size for other message types. The default value in the stream head is INFPSZ, the maximum STREAMS allows.
SO_HIWAT — Change the flow control high–water mark (q_hiwat in the queue(9S) structure, qb_hiwat in the qband(9S) structure) on the stream-head read queue to the value specified in so_hiwat.
SO_LOWAT — Change the flow control low–water mark (q_lowat in the queue(9S) structure, qb_lowat in the qband(9S) structure) on the stream-head read queue to the value specified in so_lowat.
SO_MREADON — Enable the stream head to generate M_READ messages when processing a read(2) system call. If both SO_MREADON and SO_MREADOFF are set in so_flags, SO_MREADOFF takes precedence.
SO_MREADOFF — Disable the stream head generation of M_READ messages when processing a read(2) system call. This is the default. If both SO_MREADON and SO_MREADOFF are set in so_flags, SO_MREADOFF takes precedence.
SO_NDELON — Set non-STREAMS TTY semantics for O_NDELAY(or O_NONBLOCK) processing on read(2) and write(2). If O_NDELAY(or O_NONBLOCK) is set, a read(2) returns 0 if no data is waiting to be read at the stream head. If O_NDELAY(or O_NONBLOCK) is clear, a read(2) blocks until data become available at the stream head. (See note below.)
Regardless of the state of O_NDELAY (or O_NONBLOCK), a write(2) blocks on flow control and blocks if buffers are not available.
If both SO_NDELON and SO_NDELOFF are set in so_flags, SO_NDELOFF takes precedence.
Note - For conformance with the POSIX standard, new applications should use the O_NONBLOCK flag whose behavior is the same as that of O_NDELAY unless otherwise noted.
SO_NDELOFF — Set STREAMS semantics for O_NDELAY (or O_NONBLOCK) processing on read(2) and write(2) system calls. If O_NDELAY(or O_NONBLOCK) is set, a read(2) will return -1 and set EAGAIN if no data is waiting to be read at the stream head. If O_NDELAY (or O_NONBLOCK) is clear, a read(2) blocks until data become available at the stream head. (See note above.)
If O_NDELAY (or O_NONBLOCK) is set, a write(2) returns -1 and sets EAGAIN if flow control is in effect when the call is received. It blocks if buffers are not available. If O_NDELAY (or O_NONBLOCK) is set, part of the buffer has been written, and a flow control or “buffers not available” condition is encountered, write(2) terminates and returns the number of bytes written.
If O_NDELAY (or O_NONBLOCK) is clear, a write(2) will block on flow control and will block if buffers are not available.
This is the default. If both SO_NDELON and SO_NDELOFF are set in so_flags, SO_NDELOFF takes precedence.
In the STREAMS-based pipe mechanism, the behavior of read(2) and write(2) is different for the O_NDELAY and O_NONBLOCK flags.
SO_BAND — Set watermarks in a band. If the SO_BAND flag is set with the SO_HIWAT or SO_LOWAT flag, the so_band field contains the priority band number related to the so_hiwat and so_lowat fields.
If the SO_BAND flag is not set and the SO_HIWAT and SO_LOWAT flags are on, the normal high-water and low-water marks are affected. The SO_BAND flag has no effect if SO_HIWAT and SO_LOWAT flags are off.
Only one band's water marks can be updated with a single M_SETOPTS message.
SO_ISTTY — Inform the stream head that the stream is acting like a controlling terminal.
SO_ISNTTY — Inform the stream head that the stream is no longer acting like a controlling terminal.
For SO_ISTTY, the stream may be allocated as a controlling terminal via an M_SETOPTS message arriving upstream during open processing. If the stream head is opened before receiving this message, the stream will not be allocated as a controlling terminal until it is queued again by a session leader.
SO_TOSTOP — Stop on background writes to the stream.
SO_TONSTOP — Do not stop on background writes to the stream. SO_TOSTOP and SO_TONSTOP are used in conjunction with job control.
SO_DELIM — Messages are delimited.
SO_NODELIM — Messages are not delimited.
SO_STRHOLD — Enable strwrite message coalescing.
The M_SIG message is sent upstream by modules or drivers to post a signal to a process. When the message reaches the front of the stream-head read queue, it evaluates the first data byte of the message as a signal number, defined in <sys/signal.h>. (The signal is not generated until it reaches the front of the stream-head read queue.) The associated signal will be sent to processes under the following conditions:
If the signal is SIGPOLL, it is sent only to those processes that have explicitly registered to receive the signal (see I_SETSIG in streamio(7I)).
If the signal is not SIGPOLL and the stream containing the sending module or driver is a controlling TTY, the signal is sent to the associated process group. A stream becomes the controlling TTY for its process group if, on open(2) a module or driver sends an M_SETOPTS message to the stream head with the SO_ISTTY flag set.
If the signal is not SIGPOLL and the stream is not a controlling TTY, no signal is sent, except in case of SIOCSPGRP and TIOCSPGRP. These two ioctls set the process group field in the stream head so the stream can generate signals even if it is not a controlling TTY.