CMSG_DATA(3) | Library Functions Manual | CMSG_DATA(3) |
CMSG_DATA
, CMSG_FIRSTHDR
,
CMSG_LEN
, CMSG_NXTHDR
,
CMSG_SPACE
—
#include <sys/socket.h>
void *
CMSG_DATA
(struct
cmsghdr *);
struct cmsghdr *
CMSG_FIRSTHDR
(struct
msghdr *);
size_t
CMSG_LEN
(size_t);
struct cmsghdr *
CMSG_NXTHDR
(struct
msghdr *, struct cmsghdr
*);
size_t
CMSG_SPACE
(size_t);
Control messages are passed around by the recvmsg(2) and sendmsg(2) system calls. The cmsghdr structure, described in recvmsg(2), is used to specify a chain of control messages.
These routines should be used instead of directly accessing the control message header members and data buffers as they ensure that necessary alignment constraints are met.
The following routines are provided:
CMSG_DATA
(cmsg)CMSG_FIRSTHDR
(mhdr)NULL
.CMSG_LEN
(len)CMSG_NXTHDR
(mhdr,
cmsg)NULL
.CMSG_SPACE
(len)struct msghdr msg; struct cmsghdr *cmsg; union { struct cmsghdr hdr; unsigned char buf[CMSG_SPACE(sizeof(int))]; } cmsgbuf; memset(&msg, 0, sizeof(msg)); msg.msg_control = &cmsgbuf.buf; msg.msg_controllen = sizeof(cmsgbuf.buf); cmsg = CMSG_FIRSTHDR(&msg); cmsg->cmsg_len = CMSG_LEN(sizeof(int)); cmsg->cmsg_level = SOL_SOCKET; cmsg->cmsg_type = SCM_RIGHTS; *(int *)CMSG_DATA(cmsg) = fd; if (sendmsg(s, &msg, 0) == -1) err(1, "sendmsg");
And an example that receives and decomposes the control message:
struct msghdr msg; struct cmsghdr *cmsg; union { struct cmsghdr hdr; unsigned char buf[CMSG_SPACE(sizeof(int))]; } cmsgbuf; memset(&msg, 0, sizeof(msg)); msg.msg_control = &cmsgbuf.buf; msg.msg_controllen = sizeof(cmsgbuf.buf); if (recvmsg(s, &msg, 0) == -1) err(1, "recvmsg"); if ((msg.msg_flags & MSG_TRUNC) || (msg.msg_flags & MSG_CTRUNC)) errx(1, "control message truncated"); for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) { if (cmsg->cmsg_len == CMSG_LEN(sizeof(int)) && cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) { fd = *(int *)CMSG_DATA(cmsg); /* Do something with the descriptor. */ } }
March 24, 2008 | OpenBSD-5.8 |