The STREAMS functions provided by the kernel are documented in the man pages, section 9F, "DDI/DKI Functions." The DDI/DKI is the set of supported routines for use by driver or module writers. We'll point out a few you might see: -
allocb() ” Allocates buffers. This routine returns a pointer to a linked message block and data block pair, since one must be used with the other, plus a data buffer of the specified size . If no space is available, this routine should return immediately with a null pointer. -
copyb() ” Creates a new copy of a message; message block, data block, and data are duplicated . This routine uses allocb() to get the space. -
copymsg() ” Copies a complete message, possibly consisting of multiple message blocks. -
dupb() ” Creates a message block that points to the same data block (and data buffer) as an existing message block. -
dupmsg() ” Proceeds through a list of message blocks, using dupb() for each, to create a new set of message block headers referring to the same data as the original. -
esballoc() ” Allocates a message that points to a data buffer already allocated and provided. It makes provisions for a callback function: one that will be called when the buffer is freed. Since it has not been allocated by the STREAMS functions, something else must take care of returning the buffer to a free list or reusing it somehow. Otherwise, the buffer will be thrown away, and a nice memory leak will result. -
freeb() ” Frees a message block. If the data block it refers to is not pointed to by any other message, then that data block and buffer will be freed as well. -
freemsg() ” Performs the freeb() function on all blocks of a message. -
put() - ” Places a message directly on the supplied queue. This routine can be used by a module to place data on its own queue. Note that this is a system routine; individual modules will have to name their own put procedures to be something unique. -
putctl() ” Creates a control message, fills it in with the right type code, and puts it on the specified queue. It will not pass any data along (many control messages don't need any). If necessary, putctl1() , a variation of putctl() , will create and put a control message with one byte of data (supplied as a parameter). -
putnext() ” Calls the put() procedure of the next queue in sequence. -
qprocson() ” Actually makes the queues available for use. This is an initialization function that "enables" the put and service procedures of a module. There have been instances when a device driver interrupt service function attempted to use the put procedures of newly pushed modules, or of the driver itself, before qprocson() was completely finished. This can result in unpleasant things, like panics. This list doesn't cover all the STREAMS support functions, but these are some of the more commonly used ones and some that have been seen on stack tracebacks of hung or crashed systems. |