blob: 9522ba14e19bc3dbf3ebeac5720ffdc99e6662ae [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;
18 struct iovec iov = {
19 .iov_base = &fd,
20 .iov_len = sizeof(iov)
21 };
22
23 struct msghdr mh = {
24 .msg_iov = &iov,
25 .msg_iovlen = 1,
26 .msg_control = &control,
27 .msg_controllen = sizeof(control)
28 };
29
30 while ((fd = open("/dev/null", O_RDWR)) < 3)
31 assert(fd >= 0);
32 (void) close(3);
33
34 int sv[2];
35 assert(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == 0);
36
37 pid_t pid = fork();
38 assert(pid >= 0);
39
40 if (pid) {
41 assert(close(sv[0]) == 0);
42 assert(dup2(sv[1], 1) == 1);
43 assert(close(sv[1]) == 0);
44
45 assert((fd = open("/dev/null", O_RDWR)) == 3);
46
47 struct cmsghdr *cmsg = CMSG_FIRSTHDR(&mh);
48 cmsg->cmsg_level = SOL_SOCKET;
49 cmsg->cmsg_type = SCM_RIGHTS;
50 cmsg->cmsg_len = CMSG_LEN(sizeof fd);
51 memcpy(CMSG_DATA(cmsg), &fd, sizeof fd);
52 mh.msg_controllen = cmsg->cmsg_len;
53
54 assert(sendmsg(1, &mh, 0) == sizeof(iov));
55 assert(close(1) == 0);
56
57 int status;
58 assert(waitpid(pid, &status, 0) == pid);
59 assert(status == 0);
60 } else {
61 assert(close(sv[1]) == 0);
62 assert(dup2(sv[0], 0) == 0);
63 assert(close(sv[0]) == 0);
64
65 assert(recvmsg(0, &mh, 0) == sizeof(iov));
66 assert(close(0) == 0);
67 }
68
69 return 0;
70}