blob: 0cced9becbcebc7ab644bd966f229df44f04c7f9 [file] [log] [blame]
Dmitry V. Levinf23b0972014-05-29 21:35:34 +00001#include <assert.h>
2#include <string.h>
3#include <stdlib.h>
4#include <unistd.h>
5#include <errno.h>
6#include <fcntl.h>
7#include <sys/socket.h>
8#include <sys/wait.h>
9
10int main(void)
11{
12 union {
13 struct cmsghdr cmsghdr;
14 char buf[CMSG_SPACE(sizeof(int))];
15 } control = {};
16
17 int fd;
Dmitry V. Levine25fb4f2014-05-30 15:18:00 +000018 int data = 0;
Dmitry V. Levinf23b0972014-05-29 21:35:34 +000019 struct iovec iov = {
Dmitry V. Levine25fb4f2014-05-30 15:18:00 +000020 .iov_base = &data,
Dmitry V. Levinf23b0972014-05-29 21:35:34 +000021 .iov_len = sizeof(iov)
22 };
23
24 struct msghdr mh = {
25 .msg_iov = &iov,
26 .msg_iovlen = 1,
27 .msg_control = &control,
28 .msg_controllen = sizeof(control)
29 };
30
31 while ((fd = open("/dev/null", O_RDWR)) < 3)
32 assert(fd >= 0);
33 (void) close(3);
34
35 int sv[2];
36 assert(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == 0);
37
38 pid_t pid = fork();
39 assert(pid >= 0);
40
41 if (pid) {
42 assert(close(sv[0]) == 0);
43 assert(dup2(sv[1], 1) == 1);
44 assert(close(sv[1]) == 0);
45
46 assert((fd = open("/dev/null", O_RDWR)) == 3);
47
48 struct cmsghdr *cmsg = CMSG_FIRSTHDR(&mh);
49 cmsg->cmsg_level = SOL_SOCKET;
50 cmsg->cmsg_type = SCM_RIGHTS;
51 cmsg->cmsg_len = CMSG_LEN(sizeof fd);
52 memcpy(CMSG_DATA(cmsg), &fd, sizeof fd);
53 mh.msg_controllen = cmsg->cmsg_len;
54
55 assert(sendmsg(1, &mh, 0) == sizeof(iov));
56 assert(close(1) == 0);
57
58 int status;
59 assert(waitpid(pid, &status, 0) == pid);
60 assert(status == 0);
61 } else {
62 assert(close(sv[1]) == 0);
63 assert(dup2(sv[0], 0) == 0);
64 assert(close(sv[0]) == 0);
65
66 assert(recvmsg(0, &mh, 0) == sizeof(iov));
67 assert(close(0) == 0);
68 }
69
70 return 0;
71}