]> granicus.if.org Git - strace/blob - tests/scm_rights.c
Impove struct cmsghdr decoding
[strace] / tests / scm_rights.c
1 #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
10 int main(void)
11 {
12         int fd;
13         int data = 0;
14         struct iovec iov = {
15                 .iov_base = &data,
16                 .iov_len = sizeof(iov)
17         };
18
19         while ((fd = open("/dev/null", O_RDWR)) < 3)
20                 assert(fd >= 0);
21         (void) close(3);
22
23         int sv[2];
24         assert(socketpair(AF_UNIX, SOCK_STREAM, 0, sv) == 0);
25         int one = 1;
26         assert(setsockopt(sv[0], SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) == 0);
27
28         pid_t pid = fork();
29         assert(pid >= 0);
30
31         if (pid) {
32                 assert(close(sv[0]) == 0);
33                 assert(dup2(sv[1], 1) == 1);
34                 assert(close(sv[1]) == 0);
35
36                 int fds[2];
37                 assert((fds[0] = open("/dev/null", O_RDWR)) == 3);
38                 assert((fds[1] = open("/dev/zero", O_RDONLY)) == 4);
39
40                 union {
41                         struct cmsghdr cmsg;
42                         char buf[CMSG_LEN(sizeof(fds))];
43                 } control = {
44                         .cmsg = {
45                                 .cmsg_level = SOL_SOCKET,
46                                 .cmsg_type = SCM_RIGHTS,
47                                 .cmsg_len = CMSG_LEN(sizeof(fds))
48                         }
49                 };
50
51                 memcpy(CMSG_DATA(&control.cmsg), fds, sizeof(fds));
52
53                 struct msghdr mh = {
54                         .msg_iov = &iov,
55                         .msg_iovlen = 1,
56                         .msg_control = &control,
57                         .msg_controllen = sizeof(control)
58                 };
59
60                 assert(sendmsg(1, &mh, 0) == sizeof(iov));
61                 assert(close(1) == 0);
62
63                 int status;
64                 assert(waitpid(pid, &status, 0) == pid);
65                 assert(status == 0);
66         } else {
67                 assert(close(sv[1]) == 0);
68                 assert(dup2(sv[0], 0) == 0);
69                 assert(close(sv[0]) == 0);
70
71                 struct cmsghdr control[4];
72
73                 struct msghdr mh = {
74                         .msg_iov = &iov,
75                         .msg_iovlen = 1,
76                         .msg_control = control,
77                         .msg_controllen = sizeof(control)
78                 };
79
80                 assert(recvmsg(0, &mh, 0) == sizeof(iov));
81                 assert(close(0) == 0);
82         }
83
84         return 0;
85 }