CMSG_DATA(3) | Library Functions Manual | CMSG_DATA(3) |
CMSG_DATA
,
CMSG_FIRSTHDR
, CMSG_LEN
,
CMSG_NXTHDR
, CMSG_SPACE
— socket control message routines
#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);
The control message API is used to construct ancillary data objects for use in control messages sent and received across sockets.
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)The following example constructs a control message containing a file descriptor and passes it over a socket:
struct msghdr msg; struct cmsghdr *cmsg; union { struct cmsghdr hdr; unsigned char buf[CMSG_SPACE(sizeof(int))]; } cmsgbuf; struct iovec io_vector[1]; io_vector[0].iov_base = &ch; io_vector[0].iov_len = 1; memset(&msg, 0, sizeof(msg)); msg.msg_control = &cmsgbuf.buf; msg.msg_controllen = sizeof(cmsgbuf.buf); msg.msg_iov = io_vector; msg.msg_iovlen = 1; 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; struct iovec io_vector[1]; io_vector[0].iov_base = &ch; io_vector[0].iov_len = 1; memset(&msg, 0, sizeof(msg)); msg.msg_control = &cmsgbuf.buf; msg.msg_controllen = sizeof(cmsgbuf.buf); msg.msg_iov = io_vector; msg.msg_iovlen = 1; 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. */ } }
The control message API first appeared in 4.2BSD.
April 3, 2017 | OpenBSD-6.9 |