M_COPYOUT Example
Note - Please see the copyout section in Writing Device Drivers for information on the 64-bit data structure macros.
The following code excerpts return option values for the STREAMS device by placing them in the user's options structure. This is done by a transparent ioctl(2) call of the form
struct options optadd; ioctl(fd, GET_OPTIONS,(caddr_t) &optadd) |
or by a nontransparent I_STR call
struct strioctl opts_strioctl; structure options optadd; opts_strioctl.ic_cmd = GET_OPTIONS; opts_strioctl.ic_timeout = -1 opts_strioctl.ic_len = sizeof (struct options); opts_strioctl.ic_dp = (char *)&optadd; ioctl(fd, I_STR, (caddr_t) &opts_strioctl) |
In the nontransparent I_STR case, opts_strioctl.ic_dp points to the options structure optadd.
Example 8-7 illustrates support of both the I_STR and transparent forms of ioctl(2). The transparent form requires a single M_COPYOUT message following receipt of the M_IOCTL to copy out the contents of the structure. xxwput() is the write-side put procedure of module or driver xx.
xxwput() first checks whether the ioctl(2) command is transparent. If it is, the message is reused as an M_COPYOUT copy request message. The pointer to the receiving buffer is in the linked message and is copied into cq_addr. Because only a single copy out is being done, no state information needs to be stored in cq_private. The original linked message is freed, in case it isn't big enough to hold the request.
if (iocbp->ioc_count == TRANSPARENT) {
transparent = 1;
cqp = (struct copyreq *)mp->b_rptr;
cqp->cq_size = sizeof(struct options);
/* Get struct address from linked M_DATA block */
cqp->cq_addr = (caddr_t)
*(caddr_t *)mp->b_cont->b_rptr;
cqp->cq_flag = 0;
/* No state necessary - we will only ever get one
* M_IOCDATA from the Stream head indicating
* success or failure for the copyout */
}
if (mp->b_cont)
freemsg(mp->b_cont);
|



