1 .\" Written by Jared Yanovich <jaredy@openbsd.org>
2 .\" Public domain, July 3, 2005
14 .Nd socket control message routines for ancillary data access
18 .Fn CMSG_DATA "struct cmsghdr *"
20 .Fn CMSG_FIRSTHDR "struct msghdr *"
24 .Fn CMSG_NXTHDR "struct msghdr *" "struct cmsghdr *"
26 .Fn CMSG_SPACE "size_t"
28 The control message API is used to construct ancillary data objects for
29 use in control messages sent and received across sockets.
31 Control messages are passed around by the
38 structure, described in
40 is used to specify a chain of control messages.
42 These routines should be used instead of directly accessing the control
43 message header members and data buffers as they ensure that necessary
44 alignment constraints are met.
46 The following routines are provided:
49 This routine accesses the data portion of the control message header
51 It ensures proper alignment constraints on the beginning of ancillary
53 .It Fn CMSG_FIRSTHDR msghdr
54 This routine accesses the first control message attached to the
57 If no control messages are attached to the message, this routine
61 This routine determines the size in bytes of a control message,
62 which includes the control message header.
64 specifies the length of the data held by the control message.
65 This value is what is normally stored in the
67 of each control message.
68 This routine accounts for any alignment constraints on the beginning of
70 .It Fn CMSG_NXTHDR msghdr cmsg
71 This routine returns the location of the control message following
77 is the last control message in the chain, this routine returns
80 This routine determines the size in bytes needed to hold a control
81 message and its contents of length
83 which includes the control message header.
84 This value is what is normally stored in
85 .Fa msg_msgcontrollen .
86 This routine accounts for any alignment constraints on the beginning of
87 ancillary data as well as any needed to pad the next control message.
90 The following example constructs a control message containing a file descriptor
91 in the parent process and passes it over a pre-shared socket over the child
93 Then the child process sends a "hello" string to the parent process using the
94 received file descriptor.
96 #include <sys/socket.h>
101 #include <sysexits.h>
104 #define HELLOLEN sizeof("hello")
112 unsigned char buf[CMSG_SPACE(sizeof(int))];
117 struct cmsghdr *cmsg;
119 if (socketpair(PF_LOCAL, SOCK_STREAM, 0, presharedfd) == -1)
120 err(EX_OSERR, "failed to create a pre-shared socket pair");
122 memset(&msg, 0, sizeof(msg));
123 msg.msg_control = &cmsgbuf.buf;
124 msg.msg_controllen = sizeof(cmsgbuf.buf);
130 err(EX_OSERR, "fork");
132 close(presharedfd[0]);
133 strlcpy(buf, "hello", HELLOLEN);
135 if (recvmsg(presharedfd[1], &msg, 0) == -1)
136 err(EX_IOERR, "failed to receive a message");
137 if (msg.msg_flags & (MSG_CTRUNC | MSG_TRUNC))
138 errx(EX_IOERR, "control message truncated");
139 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
140 cmsg = CMSG_NXTHDR(&msg, cmsg)) {
141 if (cmsg->cmsg_len == CMSG_LEN(sizeof(int)) &&
142 cmsg->cmsg_level == SOL_SOCKET &&
143 cmsg->cmsg_type == SCM_RIGHTS) {
144 hellofd[1] = *(int *)CMSG_DATA(cmsg);
145 printf("child: sending '%s'\\n", buf);
146 if (write(hellofd[1], buf, HELLOLEN) == -1)
147 err(EX_IOERR, "failed to send 'hello'");
152 close(presharedfd[1]);
154 if (socketpair(PF_LOCAL, SOCK_STREAM, 0, hellofd) == -1)
155 err(EX_OSERR, "failed to create a 'hello' socket pair");
157 cmsg = CMSG_FIRSTHDR(&msg);
158 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
159 cmsg->cmsg_level = SOL_SOCKET;
160 cmsg->cmsg_type = SCM_RIGHTS;
161 *(int *)CMSG_DATA(cmsg) = hellofd[1];
163 if (sendmsg(presharedfd[0], &msg, 0) == -1)
164 err(EX_IOERR, "sendmsg");
167 if (read(hellofd[0], buf, HELLOLEN) == -1)
168 err(EX_IOERR, "faild to receive 'hello'");
169 printf("parent: received '%s'\\n", buf);
189 .%T "Advanced Sockets API for IPv6"
199 .%T "Advanced Sockets Application Program Interface (API) for IPv6"
205 The control message API first appeared in
207 This manual page was originally written by
208 .An Jared Yanovich Aq Mt jaredy@OpenBSD.org
211 and eventually brought to
214 .An Mateusz Piotrowski Aq Mt 0mp@FreeBSD.org .