STREAMS Programming Guide

Using Pipes and FIFOs

Pipes and FIFOs can be accessed through the operating system routines read(2), write(2), ioctl(2), close(2), putmsg(2), putpmsg(2), getmsg(2), getpmsg(2), and poll(2). For FIFOs, open(2) is also used.

Reading From a Pipe or FIFO

read(2) or getmsg(2)) are used to read from a pipe or FIFO. Data can be read from either end of a pipe. On success, the read(2) returns the number of bytes read and buffered. When the end of the data is reached, read(2) returns 0.

When a user process attempts to read from an empty pipe (or FIFO), the following happens:

Writing to a Pipe or FIFO

When a user process calls write(2), data is sent down the associated stream. If the pipe or FIFO is empty (no modules pushed), the data that is written is placed on the read queue of the other stream for pipes, and on the read queue of the same stream for FIFOs. Since the size of a pipe is the number of unread data bytes, the written data is reflected in the size of the other end of the pipe.

Zero-Length Writes

If a user process issues write(2) with 0 as the number of bytes to send a pipe or FIFO, 0 is returned, and, by default, no message is sent down the stream. However, if a user must send a zero-length message downstream, SNDZERO ioctl(2) can be used to change this default behavior. If SNDZERO is set in the stream head, write(2) requests of 0 bytes generate a zero-length message and send the message down the stream. If SNDZERO is not set, no message is generated and 0 is returned to the user.

The SNDZERO bit may be changed by the I_SWROPT ioctl(2). If the arg in the ioctl(2) has SNDZERO set, the bit is turned on. If the arg is set to 0, the SNDZERO bit is turned off.

The I_GWROPT ioctl(2) is used to get the current write settings.

Atomic Writes

If multiple processes simultaneously write to the same pipe, data from one process can be interleaved with data from another process, if modules are pushed on the pipe or the write is greater than PIPE_BUF. The order of data that is written is not necessarily the order of data that is read. To ensure that writes of less than PIPE_BUF bytes are not interleaved with data written by other processes, any modules pushed on the pipe should have a maximum packet size of at least PIPE_BUF.

Note –

PIPE_BUF is an implementation-specific constant that specifies the maximum number of bytes that are atomic when writing to a pipe. When writing to a pipe, write requests of PIPE_BUF or fewer bytes are not interleaved with data from other processes doing writes to the same pipe. However, write requests of more than PIPE_BUF bytes may have data interleaved on arbitrary byte boundaries with writes by other processes whether or not the O_NONBLOCK or O_NDELAY flag is set.

If the module packet size is at least the size of PIPE_BUF, the stream head packages the data in such a way that the first message is at least PIPE_BUF bytes. The remaining data may be packaged into smaller or equal-sized blocks depending on buffer availability. If the first module on the stream cannot support a packet of PIPE_BUF, atomic writes on the pipe cannot be guaranteed.

Closing a Pipe or FIFO

close(2) closes a pipe or FIFO and dismantles its associated streams. On the last close of one end of a pipe, an M_HANGUP message is sent to the other end of the pipe. Subsequent read(2) or getmsg(2) calls on that stream head return the number of bytes read and zero when there are no more data. Subsequent write(2) or putmsg(2) requests fail with errno set to EPIPE. If the other end of the pipe is mounted, the last close of the pipe forces it to be unmounted.