31.3 getmsg
and putmsg Functions
The data transferred up and down a stream
consists of messages, and each message contains control, data, or both. If we use read and
write on a stream, these transfer only data. To allow a
process to read and write both data and control information, two
new functions were added.
#include <stropts.h>
|
int getmsg(int fd, struct strbuf *ctlptr, struct strbuf *dataptr, int *flagsp) ;
|
int putmsg(int fd, const struct strbuf *ctlptr, const struct strbuf
*dataptr, int
flags) ;
|
Both return: non-negative value if OK (see
text), 鈥? on error
|
Both the control and data portions of the
message are described by the following strbuf
structure:
struct strbuf {
int maxlen; /* maximum size of buf */
int len; /* actual amount of data in buf */
char *buf; /* data */
};
Note the similarity between the strbuf
structure and the netbuf structure. The names of the three
elements in each structure are identical.
But the two lengths in the netbuf
structure are unsigned integers, while the two lengths in the
strbuf structure are signed integers. The reason why is
that some of the STREAMS functions use a len or
maxlen value of 鈥? to indicate something special.
We can send only control information, only data,
or both using putmsg. To indicate the absence of control
information, we can either specify ctlptr as a null pointer or set ctlptr->len to 鈥?. The same technique is
used to indicate no data.
If there is no control information, an
M_DATA message is generated by putmsg (Figure
31.6); otherwise, either an M_PROTO or an
M_PCPROTO message is generated, depending on the
flags. The flags argument to putmsg is 0 for a
normal message or RS_HIPRI for a high-priority
message.
The final argument to getmsg is a
value-result argument. If the integer pointed to by flagsp is 0 when the function is called, the
first message on the stream is returned (which can be normal- or
high-priority). If the integer value is RS_HIPRI when the
function is called, the function waits for a high-priority message
to arrive at the stream head. In both cases, the value stored in
the integer pointed to by flagsp
will be 0 or RS_HIPRI, depending on the type of message
returned.
Assuming we pass non-null ctlptr and dataptr values to getmsg, if there is
no control information to return (i.e., an M_DATA message
is being returned), this is indicated by setting ctlptr->len to 鈥? on return. Similarly,
dataptr->len is set to 鈥? if
there is no data to return.
The return value from putmsg is 0 if
all is okay, or 鈥? on an error. But, getmsg returns 0 only
if the entire message was returned to the caller. If the control
buffer is too small for all the control information, the return
value is MORECTL (which is guaranteed to be non-negative).
Similarly, if the data buffer is too small, MOREDATA can
be returned. If both are too small, the logical OR of these two
flags is returned.
|