STREAMS-UX Programmer's Guide (February 2007)
Modules and Drivers
Entry Points
Chapter 4
76
7. If the module needs to send data back to the user, a M_COPYOUT message is created by the module and sent
to the stream head. The stream head executes a copyout() function that copies the data from the
M_COPYOUT message into the user buffer. The M_COPYOUT message contains the address of user data, size
and the data. The M_IOCDATA response for the M_COPYOUT will not contain data but only an indication of
success or failure.
The format of a M_COPYIN message is one message block of type M_COPYIN, whose data buffer contains a
copyreq structure as defined. The format of a M_COPYOUT message is one message block of M_COPYOUT, linked
to one more M_DATA blocks containing data to be copied to the user’s buffer. The data buffer in a M_COPYOUT
message also contains a copyreq structure. The format of M_IOCDATA message is one message block of type
M_IOCDATA, linked to zero or more M_DATA blocks. The data buffer of M_IOCDATA contains a copyresp
structure as defined.
The copyreq structure in M_COPYIN/M_COPYOUT messages used to communicate requests from the modules to
stream head is defined in <sys/stream.h> and contains the following fields:
int cq_cmd; /* command type == ioc_cmd */
cred_t * cq_cr; /* pointer to full credentials */
uint cq_id; /* ioctl id == ioc_id */
int cq_flag; /* reserved */
mblk_t * cq_private; /* module's private state info */
ioc_pad cq_ad; /* address to copy data to/from */
uint cq_size; /* number of bytes to copy */
If a new copyreq message is allocated for M_COPYIN/M_COPYOUT request, modules must copy the values of
cq_cmd, cq_cr and cq_id from the M_IOCTL or M_IOCDATA message into respective fields of the new message.
These fields should not be modified. The cq_ad refers to the address of the data buffer from which data needs
to be copied in for an M_COPYIN message, while it refers to the address of the buffer from which data needs to
be copied out for a M_COPYOUT request. The cq_size specifies the number of bytes to be copied. Both cq_ad
and cq_size values need to be set by the modules. The cq_private can be set by the modules to get their
state information.
The copyresp structure in M_IOCDATA used to communicate the results of copyin()/copyout() from the
stream head back to the modules is defined in <sys/stream.h> and contains the following fields:
int cp_cmd; /* command type == ioc_cmd */
cred_t * cp_cr; /* pointer to full credentials */
uint cp_id; /* ioctl id == ioc_id */
uint cp_flag; /* flag values */
mblk_t * cp_private; /* module's private state info */
ioc_pad cp_rv; /* 0 = success */
The values of cp_cmd, cp_cr, cp_id, cp_flag and cp_private refer to the cq_cmd, cq_cr, cq_id, cq_flag
and cq_private fields respectively in the copyreq structure of M_COPYIN/M_COPYOUT messages. In response
to the M_COPYIN message, the M_DATA portion of the M_IOCDATA contains the data copied in from the user
buffer. In response to a M_COPYOUT message, there are no M_DATA blocks present, instead an indication of
whether or not copy succeeded is returned through cp_rv. The cp_rv is set to zero in case of success and it is
set to error number in case of failure.
A module may intersperse M_COPYIN and M_COPYOUT messages as required. The only requirement is that only
one such request may be pending at any time, i.e., prior to issuing the next M_COPYIN or M_COPYOUT, the
module must wait until it receives the M_IOCDATA message from a previous copy request.