Sun Microsystems, Inc.
spacerspacer
spacer www.sun.com docs.sun.com |
spacer
black dot
 
 
A.  Message Types Ordinary Messages M_SETOPTS  Previous   Contents   Next 
   
 

M_SIG

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.

High-Priority Messages

High-priority messages are particularly suitable for acknowledging service requests when the acknowledgement should be placed ahead of any other messages at the stream head. High-priority messages are not subject to flow control.

M_COPYIN

The M_COPYIN message is generated by a module or driver and sent upstream to request that the stream head perform a copyin(9F) on behalf of the module or driver. It is valid only after receiving an M_IOCTL message and before an M_IOCACK or M_IOCNAK.

The message format is one M_COPYIN message block containing a copyreq(9S) structure, defined in <sys/stream.h>. Different structures are defined for 64-bit and 32-bit architectures.

#if defined(_LP64)
struct copyreq {
	int      cq_cmd;                /* ioctl command (from ioc_cmd) */
	cred_t   *cq_cr;                /* full credentials (from ioc_cmd) */
	uint     cq_id;                 /* ioctl id (from ioc_id) */
	uint     cq_flag;               /* see below */
	mblk_t   *cq_private;           /* private state information */
	caddr_t  cq_addr;               /* address to copy data to/from */
	size_t   cq_size;               /* number of bytes to copy */
};
#else
struct copyreq {
	int      cq_cmd;                /* ioctl command (from ioc_cmd) */
	cred_t   *cq_cr;                /* full credentials */
	uint     cq_id;                 /* ioctl id (from ioc_id) */
	caddr_t  cq_addr;               /* address to copy data to/from */
	size_t   cq_size;               /* number of bytes to copy */
	uint     cq_flag;               /* see below */
	mblk_t   *cq_private;           /* private state information */
	int      cq_filler[4];          /* reserved for future use */
};
#endif   /* _LP64 */

The first four members of the structure correspond to those of the iocblk(9S) structure in the M_IOCTL message that allows the same message block to be reused for both structures. The stream head guarantees that the message block allocated for the M_IOCTL message is large enough to contain a copyreq(9S). The cq_addr field contains the user space address from which the data is to be copied. The cq_size field is the number of bytes to copy from user space. The cq_flag field is reserved for future use and should be set to zero.

This message should not be queued by a module or driver unless it intends to process the data for the ioctl(2).

M_COPYOUT

The M_COPYOUT message is generated by a module or driver and sent upstream to request that the stream head perform a copyout(9F) on behalf of the module or driver. It is valid only after receiving an M_IOCTL message and before an M_IOCACK or M_IOCNAK.

The message format is one M_COPYOUT message block followed by one or more M_DATA blocks. The M_COPYOUT message block contains a copyreq(9S) as described in the M_COPYIN message with the following differences: the cq_addr field contains the user space address to which the data is to be copied. The cq_size field is the number of bytes to copy to user space.

Data to be copied to user space is contained in the linked M_DATA blocks.

This message should not be queued by a module or driver unless it processes the data for the ioctl in some way.


Note - For more information, see copyin and copyout in the Writing Device Drivers manual.


M_ERROR

The M_ERROR message is sent upstream by modules or drivers to report a downstream error condition. When the message reaches the stream head, the stream is marked so that all subsequent system calls issued to the stream, excluding close(2) and poll(2), fail with errno set to the first data byte of the message. POLLERR is set if the stream is being polled. All processes sleeping on a system call to the stream are awakened. An M_FLUSH message with FLUSHRW is sent downstream.

The stream head maintains two error fields, one for the read side and one for the write side. The one-byte format M_ERROR message sets both of these fields to the error specified by the first byte in the message.

There is also a two-byte format of the M_ERROR message. The first byte is the read error and the second byte is the write error. This enables modules to set a different error on the read side and write side. If one of the bytes is set to NOERROR, then the field for the corresponding side of the stream is unchanged. The module can then ignore an error on one side of the stream. For example, if the stream head was not in an error state and a module sent an M_ERROR message upstream with the first byte set to EPROTO and the second byte set to NOERROR, all subsequent read-like system calls (such as read(2)and getmsg(2)) fail with EPROTO, but all write-like system calls (such as write(2) and putmsg(2)) still succeed. If a byte is set to 0, the error state is cleared for the corresponding side of the stream. The values NOERROR and 0 are not valid for the one-byte form of the M_ERROR message.

M_FLUSH

The M_FLUSH message requests all modules and drivers that receive it to flush their message queues (discard all messages in those queues) as indicated in the message. An M_FLUSH can originate at the stream head, or in any module or driver. The first byte of the message contains flags that specify one of the following actions:

  • FLUSHR -- Flush the read queue of the module

  • FLUSHW -- Flush the write queue of the module

  • FLUSHRW -- Flush both the read queue and the write queue of the module

  • FLUSHBAND -- Flush the message according to the priority associated with the band

Each module passes this message to its neighbor after flushing its appropriate queues until the message reaches one of the ends of the stream.

Drivers are expected to include the following processing for M_FLUSH messages. When an M_FLUSH message is sent downstream through the write queues in a stream, the driver at the stream end discards it if the message action indicates that the read queues in the stream are not to be flushed (only FLUSHW set). If the message indicates that the read queues are to be flushed, the driver shuts off the FLUSHW flag, and sends the message up the stream's read queues.

When a flush message is sent up a stream's read side, the stream head checks to see if the write side of the stream is to be flushed. If only FLUSHR is set, the stream head discards the message. However, if the write side of the stream is to be flushed, the stream head sets the M_FLUSH flag to FLUSHW and sends the message down the stream's write side. All modules that queue messages must identify and process this message type.

If FLUSHBAND is set, the second byte of the message contains the value of the priority band to flush.

M_HANGUP

The M_HANGUP message is sent upstream by a driver to report that it can no longer send data upstream. For example, this might be due to an error, or to a remote line connection being dropped. When the message reaches the stream head, the stream is marked so that all subsequent write(2) and putmsg(2) calls issued to the stream will fail and return an ENXIO error. Those ioctls that cause messages to be sent downstream are also failed. POLLHUP is set if the stream is being polled.

Subsequent read(2) or getmsg(2) calls to the stream will not generate an error. These calls will return any messages (according to their function) that were on, or in transit to, the stream-head read queue before the M_HANGUP message was received. When all such messages have been read, read(2) returns 0 and getmsg(2) will set each of its two length fields to 0.

This message also causes a SIGHUP signal to be sent to the controlling process instead of the foreground process group, as the allocation and deallocation of controlling terminals to a session is the responsibility of the controlling process.

M_IOCACK

The M_IOCACK message signals the positive acknowledgement of a previous M_IOCTL message. The message format is one M_IOCACK block (containing an iocblk(9S) structure, see M_IOCTL) followed by zero or more M_DATA blocks. The iocblk(9S) may contain a value in ioc_rval to be returned to the user process. It may also contain a value in ioc_error to be returned to the user process in errno.

If this message is responding to an I_STR ioctl (see streamio(7I)), it may contain data from the receiving module or driver to be sent to the user process. In this case, message format is one M_IOCACK block followed by one or more M_DATA blocks containing the user data. The stream head returns the data to the user if there is a corresponding outstanding M_IOCTL request. Otherwise, the M_IOCACK message is ignored and all blocks in the message are freed.

Data cannot be returned in an M_IOCACK message responding to a transparent M_IOCTL. The data must have been sent with preceding M_COPYOUT messages. If any M_DATA blocks follow the M_IOCACK block, the stream head ignores and frees them.

The format and use of this message type is described further under M_IOCTL.

 
 
 
  Previous   Contents   Next