]>
git.saurik.com Git - apple/xnu.git/blob - tests/fd_send.c
53aa3687c24107345b30374d19a8311ea9bce544
1 #include <darwintest.h>
2 #include <darwintest_utils.h>
3 #include <dispatch/dispatch.h>
6 #include <sys/socket.h>
9 T_META_NAMESPACE("xnu.fd"),
10 T_META_RUN_CONCURRENTLY(true));
13 #define SOCKETPAIR(pair) \
14 T_ASSERT_POSIX_SUCCESS(socketpair(PF_LOCAL, SOCK_STREAM, 0, pair), "socketpair")
18 send_fd(int sock
, int fd
)
20 struct iovec iovec
[1];
22 struct cmsghdr
*cmsghdrp
;
23 char buf
[CMSG_SPACE(sizeof(int))];
25 iovec
[0].iov_base
= "";
31 msg
.msg_control
= buf
;
32 msg
.msg_controllen
= CMSG_SPACE(sizeof(int));
34 cmsghdrp
= CMSG_FIRSTHDR(&msg
);
35 cmsghdrp
->cmsg_len
= CMSG_LEN(sizeof(int));
36 cmsghdrp
->cmsg_level
= SOL_SOCKET
;
37 cmsghdrp
->cmsg_type
= SCM_RIGHTS
;
39 memcpy(CMSG_DATA(cmsghdrp
), &fd
, sizeof(fd
));
41 if (sendmsg(sock
, &msg
, 0) < 0) {
49 recv_fd(int sock
, int *fdp
)
52 struct iovec iovec
[1];
54 struct cmsghdr
*cmsghdrp
;
55 char buf
[CMSG_SPACE(sizeof(int))];
57 iovec
[0].iov_base
= &c
;
64 msg
.msg_control
= buf
;
65 msg
.msg_controllen
= CMSG_SPACE(sizeof(int));
68 if (recvmsg(sock
, &msg
, 0) < 0) {
72 cmsghdrp
= CMSG_FIRSTHDR(&msg
);
73 if (cmsghdrp
== NULL
) {
77 if (cmsghdrp
->cmsg_len
!= CMSG_LEN(sizeof(int))) {
80 if (cmsghdrp
->cmsg_level
!= SOL_SOCKET
) {
83 if (cmsghdrp
->cmsg_type
!= SCM_RIGHTS
) {
87 memcpy(fdp
, CMSG_DATA(cmsghdrp
), sizeof(*fdp
));
91 T_DECL(send
, "test for 30465592")
93 int pair
[2], fd
, status
;
96 T_ASSERT_POSIX_SUCCESS(socketpair(PF_LOCAL
, SOCK_STREAM
, 0, pair
),
101 fd
= open("/dev/null", O_RDWR
);
102 T_ASSERT_POSIX_SUCCESS(fd
, "open(/dev/null)");
104 T_ASSERT_EQ(send_fd(pair
[0], fd
), 0, "send_fd");
105 T_ASSERT_POSIX_SUCCESS(close(fd
), "close(fd)");
107 T_EXPECT_POSIX_SUCCESS(waitpid(child
, &status
, 0), "waitpid");
109 T_QUIET
; T_ASSERT_EQ(recv_fd(pair
[1], &fd
), 0, "recv_fd");
110 T_QUIET
; T_ASSERT_NE(fd
, -1, "received a proper fd");
111 T_QUIET
; T_EXPECT_POSIX_SUCCESS(close(fd
), "close(fd)");
112 raise(SIGKILL
); /* do not confuse the test system */
116 T_DECL(send_kill
, "test for 30465592")
118 int pair
[2], fd
, status
;
121 T_QUIET
; SOCKETPAIR(pair
);
125 fd
= open("/dev/null", O_RDWR
);
126 T_ASSERT_POSIX_SUCCESS(fd
, "open(/dev/null)");
128 T_ASSERT_EQ(send_fd(pair
[0], fd
), 0, "send_fd");
129 T_ASSERT_POSIX_SUCCESS(close(fd
), "close(fd)");
131 T_EXPECT_POSIX_SUCCESS(kill(child
, SIGKILL
), "kill(child)");
133 T_EXPECT_POSIX_SUCCESS(waitpid(child
, &status
, 0), "waitpid");
135 T_QUIET
; T_ASSERT_EQ(recv_fd(pair
[1], &fd
), 0, "recv_fd");
136 T_QUIET
; T_ASSERT_NE(fd
, -1, "received a proper fd");
137 T_QUIET
; T_EXPECT_POSIX_SUCCESS(close(fd
), "close(fd)");
138 raise(SIGKILL
); /* do not confuse the test system */
142 T_DECL(send_sock
, "test for 30465592")
144 int pair
[2], fd
, status
;
147 T_QUIET
; SOCKETPAIR(pair
);
153 T_QUIET
; SOCKETPAIR(sock
);
155 T_ASSERT_EQ(send_fd(pair
[0], sock
[0]), 0, "send_fd");
156 T_ASSERT_POSIX_SUCCESS(close(sock
[0]), "close(sock[0])");
157 T_ASSERT_POSIX_SUCCESS(close(sock
[1]), "close(sock[1])");
159 T_EXPECT_POSIX_SUCCESS(waitpid(child
, &status
, 0), "waitpid");
161 T_QUIET
; T_ASSERT_EQ(recv_fd(pair
[1], &fd
), 0, "recv_fd");
162 T_QUIET
; T_ASSERT_NE(fd
, -1, "received a proper fd");
163 T_QUIET
; T_EXPECT_POSIX_SUCCESS(close(fd
), "close(fd)");
164 raise(SIGKILL
); /* do not confuse the test system */
168 T_DECL(send_stress
, "test for 67133384")
172 fd
= open("/dev/null", O_RDWR
);
173 T_ASSERT_POSIX_SUCCESS(fd
, "open(/dev/null)");
175 dispatch_apply(10, NULL
, ^(size_t worker
) {
176 dispatch_queue_t q
= dispatch_queue_create("receiver", NULL
);
177 dispatch_group_t g
= dispatch_group_create();
178 int pairbuf
[2], *pair
= pairbuf
;
183 dispatch_group_async(g
, q
, ^{
186 for (int i
= 0; i
< n
; i
++) {
187 T_QUIET
; T_ASSERT_EQ(recv_fd(pair
[1], &tmp
), 0, "recv_fd");
188 T_QUIET
; T_ASSERT_NE(tmp
, -1, "received a proper fd");
189 T_QUIET
; T_EXPECT_POSIX_SUCCESS(close(tmp
), "close(tmp)");
194 for (int i
= 0; i
< n
; i
++) {
196 T_QUIET
; T_ASSERT_POSIX_SUCCESS(tmp
, "dup");
197 T_QUIET
; T_ASSERT_EQ(send_fd(pair
[0], tmp
), 0, "send_fd");
198 T_QUIET
; T_EXPECT_POSIX_SUCCESS(close(tmp
), "close(tmp)");
200 dispatch_group_wait(g
, DISPATCH_TIME_FOREVER
);
202 T_PASS("sent and received %d fds in worker %zd", n
, worker
);
204 T_QUIET
; T_EXPECT_POSIX_SUCCESS(close(pair
[0]), "close(pair[0])");
205 T_QUIET
; T_EXPECT_POSIX_SUCCESS(close(pair
[1]), "close(pair[1])");