STREAMS-UX Programmer's Guide (February 2007)
Modules and Drivers
Entry Points
Chapter 4
77
The stream head converts the M_COPYIN and M_COPYOUT messages into M_IOCDATA messages by changing the
type of the message, so it is absolutely necessary that the copyreq structure be properly formed and
initialized. Also, the iocblk, copyreq and copyresp structures all overlay one another.
M_COPYIN, M_COPYOUT and M_IOCDATA are high-priority messages and are used for communication between
the module that created them and the stream head. So, no other modules between these two should process
these messages.
Transparent IOCTL Example
The user issues the transparent IOCTL as follows:
ioctl(fd, I_TRANSPARENT, &bufadd);
The module recognizes the transparent IOCTL and processes the IOCTL as follows:
struct transparent_data { int cmd; int buflen; caddr_t bufaddr; };
struct state { int st_state; struct transparent_data st_data; };
modwput(q, bp)
queue_t *q;
mblk_t *bp;
{
struct iocblk *iocbp;
struct copyresp *csp;
struct copyreq *cq;
struct state *stp, *tmp;
switch(bp->b_datap->db_type) {
...
...
case M_IOCTL:
iocbp = (struct iocblk *)bp->b_rptr;
switch(iocbp->ioc_cmd) {
...
...
case I_TRANSPARENT:
if (iocbp->ioc_count == TRANSPARENT) {
/* Reuse M_IOCTL block for M_COPYIN */
cq = (struct copyreq *)bp->b_rptr;
/* Get user structure address from linked M_DATA block */
cq->cq_addr = (caddr_t) *(long *)bp->b_cont->b_rptr;
/* free linked message */
freemsg(bp->b_cont);
bp->b_cont = nilp(mblk_t);