1 // Copyright 2017 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <assert.h>
6 #include <errno.h>
7 #include <fcntl.h>
8 #include <poll.h>
9 #include <sys/ioctl.h>
10 #include <sys/socket.h>
11 #include <sys/types.h>
12 #include <threads.h>
13 #include <unistd.h>
14
15 #include <lib/fdio/limits.h>
16 #include <lib/fdio/unsafe.h>
17 #include <lib/fdio/util.h>
18 #include <zircon/processargs.h>
19 #include <zircon/syscalls.h>
20
21 #include <unittest/unittest.h>
22
socketpair_test(void)23 bool socketpair_test(void) {
24 BEGIN_TEST;
25
26 int fds[2];
27 int status = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
28 ASSERT_EQ(status, 0, "socketpair(AF_UNIX, SOCK_STREAM, 0, fds) failed");
29
30 // write() and read() should work.
31 char buf[4] = "abc\0";
32 status = write(fds[0], buf, 4);
33 if (status < 0)
34 printf("write failed %s\n", strerror(errno));
35 EXPECT_EQ(status, 4, "write failed");
36
37 char recvbuf[4];
38 status = read(fds[1], recvbuf, 4);
39 if (status < 0)
40 printf("read failed %s\n", strerror(errno));
41 EXPECT_EQ(status, 4, "read failed");
42
43 EXPECT_EQ(memcmp(buf, recvbuf, 4), 0, "data did not make it after write+read");
44
45 // send() and recv() should also work.
46 memcpy(buf, "def", 4);
47 status = send(fds[1], buf, 4, 0);
48 if (status < 0)
49 printf("send failed %s\n", strerror(errno));
50 EXPECT_EQ(status, 4, "send failed");
51
52 status = recv(fds[0], recvbuf, 4, 0);
53 if (status < 0)
54 printf("recv failed %s\n", strerror(errno));
55
56 EXPECT_EQ(memcmp(buf, recvbuf, 4), 0, "data did not make it after send+recv");
57
58 EXPECT_EQ(close(fds[0]), 0, "close(fds[0]) failed");
59 EXPECT_EQ(close(fds[1]), 0, "close(fds[1]) failed");
60
61 END_TEST;
62 }
63
64 static_assert(EAGAIN == EWOULDBLOCK, "Assuming EAGAIN and EWOULDBLOCK have same value");
65
socketpair_shutdown_setup(int fds[2])66 bool socketpair_shutdown_setup(int fds[2]) {
67 int status = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
68 ASSERT_EQ(status, 0, "socketpair(AF_UNIX, SOCK_STREAM, 0, fds) failed");
69
70 // Set both ends to non-blocking to make testing for readability/writability easier.
71 ASSERT_EQ(fcntl(fds[0], F_SETFL, O_NONBLOCK), 0, "");
72 ASSERT_EQ(fcntl(fds[1], F_SETFL, O_NONBLOCK), 0, "");
73
74 char buf[1] = {};
75 // Both sides should be readable.
76 errno = 0;
77 status = read(fds[0], buf, sizeof(buf));
78 EXPECT_EQ(status, -1, "fds[0] should initially be readable");
79 EXPECT_EQ(errno, EAGAIN, "");
80 errno = 0;
81 status = read(fds[1], buf, sizeof(buf));
82 EXPECT_EQ(status, -1, "fds[1] should initially be readable");
83 EXPECT_EQ(errno, EAGAIN, "");
84
85 // Both sides should be writable.
86 EXPECT_EQ(write(fds[0], buf, sizeof(buf)), 1, "fds[0] should be initially writable");
87 EXPECT_EQ(write(fds[1], buf, sizeof(buf)), 1, "fds[1] should be initially writable");
88
89 EXPECT_EQ(read(fds[0], buf, sizeof(buf)), 1, "");
90 EXPECT_EQ(read(fds[1], buf, sizeof(buf)), 1, "");
91
92 return true;
93 }
94
95 #if defined(__Fuchsia__)
96 #define SEND_FLAGS 0
97 #else
98 #define SEND_FLAGS MSG_NOSIGNAL
99 #endif
100
socketpair_shutdown_rd_test(void)101 bool socketpair_shutdown_rd_test(void) {
102 BEGIN_TEST;
103
104 int fds[2];
105 socketpair_shutdown_setup(fds);
106
107 // Write a byte into fds[1] to test for readability later.
108 char buf[1] = {};
109 EXPECT_EQ(write(fds[1], buf, sizeof(buf)), 1, "");
110
111 // Close one side down for reading.
112 int status = shutdown(fds[0], SHUT_RD);
113 EXPECT_EQ(status, 0, "shutdown(fds[0], SHUT_RD)");
114 if (status != 0)
115 printf("\nerrno %d\n", errno);
116
117 // Can read the byte already written into the pipe.
118 EXPECT_EQ(read(fds[0], buf, sizeof(buf)), 1, "fds[0] should not be readable after SHUT_RD");
119
120 // But not send any further bytes
121 EXPECT_EQ(send(fds[1], buf, sizeof(buf), SEND_FLAGS), -1, "");
122 EXPECT_EQ(errno, EPIPE, "send should return EPIPE after shutdown(SHUT_RD) on other side");
123
124 // Or read any more
125 EXPECT_EQ(read(fds[0], buf, sizeof(buf)), 0, "");
126
127 EXPECT_EQ(close(fds[0]), 0, "");
128 EXPECT_EQ(close(fds[1]), 0, "");
129
130 END_TEST;
131 }
132
socketpair_shutdown_wr_test(void)133 bool socketpair_shutdown_wr_test(void) {
134 BEGIN_TEST;
135
136 int fds[2];
137 socketpair_shutdown_setup(fds);
138
139 // Close one side down for writing.
140 int status = shutdown(fds[0], SHUT_WR);
141 EXPECT_EQ(status, 0, "shutdown(fds[0], SHUT_WR)");
142 if (status != 0)
143 printf("\nerrno %d\n", errno);
144
145 char buf[1] = {};
146
147 // Should still be readable.
148 EXPECT_EQ(read(fds[0], buf, sizeof(buf)), -1, "");
149 EXPECT_EQ(errno, EAGAIN, "errno after read after SHUT_WR");
150
151 // But not writable
152 EXPECT_EQ(send(fds[0], buf, sizeof(buf), SEND_FLAGS), -1, "write after SHUT_WR");
153 EXPECT_EQ(errno, EPIPE, "errno after write after SHUT_WR");
154
155 // Should still be able to write + read a message in the other direction.
156 EXPECT_EQ(write(fds[1], buf, sizeof(buf)), 1, "");
157 EXPECT_EQ(read(fds[0], buf, sizeof(buf)), 1, "");
158
159 EXPECT_EQ(close(fds[0]), 0, "");
160 EXPECT_EQ(close(fds[1]), 0, "");
161
162 END_TEST;
163 }
164
socketpair_shutdown_rdwr_test(void)165 bool socketpair_shutdown_rdwr_test(void) {
166 BEGIN_TEST;
167
168 int fds[2];
169 socketpair_shutdown_setup(fds);
170
171 // Close one side for reading and writing.
172 int status = shutdown(fds[0], SHUT_RDWR);
173 EXPECT_EQ(status, 0, "shutdown(fds[0], SHUT_RDWR");
174 if (status != 0)
175 printf("\nerrno %d\n", errno);
176
177 char buf[1] = {};
178
179 // Writing should fail.
180 EXPECT_EQ(send(fds[0], buf, sizeof(buf), SEND_FLAGS), -1, "");
181 EXPECT_EQ(errno, EPIPE, "errno after write after SHUT_RDWR");
182
183 // Reading should return no data.
184 EXPECT_EQ(read(fds[0], buf, sizeof(buf)), 0, "");
185
186 END_TEST;
187 }
188
189 typedef struct poll_for_read_args {
190 int fd;
191 int poll_result;
192 zx_time_t poll_time;
193 } poll_for_read_args_t;
194
poll_for_read_with_timeout(void * arg)195 int poll_for_read_with_timeout(void* arg) {
196 poll_for_read_args_t* poll_args = (poll_for_read_args_t*)arg;
197 struct pollfd pollfd;
198 pollfd.fd = poll_args->fd;
199 pollfd.events = POLLIN;
200 pollfd.revents = 0;
201
202 int timeout_ms = 100;
203 zx_time_t time_before = zx_clock_get(CLOCK_MONOTONIC);
204 poll_args->poll_result = poll(&pollfd, 1, timeout_ms);
205 zx_time_t time_after = zx_clock_get(CLOCK_MONOTONIC);
206 poll_args->poll_time = time_after - time_before;
207
208 int num_readable = 0;
209 EXPECT_EQ(ioctl(poll_args->fd, FIONREAD, &num_readable), 0, "ioctl(FIONREAD)");
210 EXPECT_EQ(num_readable, 0, "");
211
212 return 0;
213 }
214
socketpair_shutdown_self_wr_poll_test(void)215 bool socketpair_shutdown_self_wr_poll_test(void) {
216 BEGIN_TEST;
217
218 int fds[2];
219 socketpair_shutdown_setup(fds);
220
221 poll_for_read_args_t poll_args = {};
222 poll_args.fd = fds[0];
223 thrd_t poll_thread;
224 int thrd_create_result = thrd_create(&poll_thread, poll_for_read_with_timeout, &poll_args);
225 ASSERT_EQ(thrd_create_result, thrd_success, "create blocking read thread");
226
227 shutdown(fds[0], SHUT_RDWR);
228
229 ASSERT_EQ(thrd_join(poll_thread, NULL), thrd_success, "join blocking read thread");
230
231 EXPECT_EQ(poll_args.poll_result, 1, "poll should have one entry");
232 EXPECT_LT(poll_args.poll_time, 100u * 1000 * 1000, "poll should not have timed out");
233
234 END_TEST;
235 }
236
socketpair_shutdown_peer_wr_poll_test(void)237 bool socketpair_shutdown_peer_wr_poll_test(void) {
238 BEGIN_TEST;
239
240 int fds[2];
241 socketpair_shutdown_setup(fds);
242
243 poll_for_read_args_t poll_args = {};
244 poll_args.fd = fds[0];
245 thrd_t poll_thread;
246 int thrd_create_result = thrd_create(&poll_thread, poll_for_read_with_timeout, &poll_args);
247 ASSERT_EQ(thrd_create_result, thrd_success, "create blocking read thread");
248
249 shutdown(fds[1], SHUT_RDWR);
250
251 ASSERT_EQ(thrd_join(poll_thread, NULL), thrd_success, "join blocking read thread");
252
253 EXPECT_EQ(poll_args.poll_result, 1, "poll should have one entry");
254 EXPECT_LT(poll_args.poll_time, 100u * 1000 * 1000, "poll should not have timed out");
255
256 END_TEST;
257 }
258
259 #define BUF_SIZE 256
260
261 typedef struct recv_args {
262 int fd;
263 int recv_result;
264 int recv_errno;
265 char buf[BUF_SIZE];
266 } recv_args_t;
267
recv_thread(void * arg)268 int recv_thread(void* arg) {
269 recv_args_t* recv_args = (recv_args_t*)arg;
270
271 recv_args->recv_result = recv(recv_args->fd, recv_args->buf, BUF_SIZE, 0u);
272 if (recv_args->recv_result < 0)
273 recv_args->recv_errno = errno;
274
275 return 0;
276 }
277
socketpair_shutdown_self_rd_during_recv_test(void)278 bool socketpair_shutdown_self_rd_during_recv_test(void) {
279 BEGIN_TEST;
280
281 int fds[2];
282 int status = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
283 ASSERT_EQ(status, 0, "socketpair(AF_UNIX, SOCK_STREAM, 0, fds) failed");
284
285 recv_args_t recv_args = {};
286 recv_args.fd = fds[0];
287 thrd_t t;
288 int thrd_create_result = thrd_create(&t, recv_thread, &recv_args);
289 ASSERT_EQ(thrd_create_result, thrd_success, "create blocking read thread");
290
291 shutdown(fds[0], SHUT_RD);
292
293 ASSERT_EQ(thrd_join(t, NULL), thrd_success, "join blocking read thread");
294
295 EXPECT_EQ(recv_args.recv_result, 0, "recv should have returned 0");
296 EXPECT_EQ(recv_args.recv_errno, 0, "recv should have left errno alone");
297
298 END_TEST;
299 }
300
socketpair_shutdown_peer_wr_during_recv_test(void)301 bool socketpair_shutdown_peer_wr_during_recv_test(void) {
302 BEGIN_TEST;
303
304 int fds[2];
305 int status = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
306 ASSERT_EQ(status, 0, "socketpair(AF_UNIX, SOCK_STREAM, 0, fds) failed");
307
308 recv_args_t recv_args = {};
309 recv_args.fd = fds[0];
310 thrd_t t;
311 int thrd_create_result = thrd_create(&t, recv_thread, &recv_args);
312 ASSERT_EQ(thrd_create_result, thrd_success, "create blocking read thread");
313
314 shutdown(fds[1], SHUT_WR);
315
316 ASSERT_EQ(thrd_join(t, NULL), thrd_success, "join blocking read thread");
317
318 EXPECT_EQ(recv_args.recv_result, 0, "recv should have returned 0");
319 EXPECT_EQ(recv_args.recv_errno, 0, "recv should have left errno alone");
320 END_TEST;
321 }
322
323 typedef struct send_args {
324 int fd;
325 int send_result;
326 int send_errno;
327 char buf[BUF_SIZE];
328 } send_args_t;
329
send_thread(void * arg)330 int send_thread(void* arg) {
331 send_args_t* send_args = (send_args_t*)arg;
332
333 send_args->send_result = send(send_args->fd, send_args->buf, BUF_SIZE, 0u);
334 if (send_args->send_result < 0)
335 send_args->send_errno = errno;
336
337 return 0;
338 }
339
socketpair_shutdown_self_wr_during_send_test(void)340 bool socketpair_shutdown_self_wr_during_send_test(void) {
341 BEGIN_TEST;
342
343 int fds[2];
344 int status = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
345 ASSERT_EQ(status, 0, "socketpair(AF_UNIX, SOCK_STREAM, 0, fds) failed");
346
347 // First, fill up the socket so the next send() will block.
348 char buf[BUF_SIZE] = {};
349 while (true) {
350 status = send(fds[0], buf, sizeof(buf), MSG_DONTWAIT);
351 if (status < 0) {
352 ASSERT_EQ(errno, EAGAIN, "send should eventually return EAGAIN when full");
353 break;
354 }
355 }
356 send_args_t send_args = {};
357 send_args.fd = fds[0];
358 thrd_t t;
359 // Then start a thread blocking on a send().
360 int thrd_create_result = thrd_create(&t, send_thread, &send_args);
361 ASSERT_EQ(thrd_create_result, thrd_success, "create blocking send thread");
362
363 shutdown(fds[0], SHUT_WR);
364
365 ASSERT_EQ(thrd_join(t, NULL), thrd_success, "join blocking send thread");
366
367 EXPECT_EQ(send_args.send_result, -1, "send should have returned -1");
368 EXPECT_EQ(send_args.send_errno, EPIPE, "send should have set errno to EPIPE");
369
370 END_TEST;
371 }
372
socketpair_shutdown_peer_rd_during_send_test(void)373 bool socketpair_shutdown_peer_rd_during_send_test(void) {
374 BEGIN_TEST;
375
376 int fds[2];
377 int status = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
378 ASSERT_EQ(status, 0, "socketpair(AF_UNIX, SOCK_STREAM, 0, fds) failed");
379
380 // First, fill up the socket so the next send() will block.
381 char buf[BUF_SIZE] = {};
382 while (true) {
383 status = send(fds[0], buf, sizeof(buf), MSG_DONTWAIT);
384 if (status < 0) {
385 ASSERT_EQ(errno, EAGAIN, "send should eventually return EAGAIN when full");
386 break;
387 }
388 }
389 send_args_t send_args = {};
390 send_args.fd = fds[0];
391 thrd_t t;
392 int thrd_create_result = thrd_create(&t, send_thread, &send_args);
393 ASSERT_EQ(thrd_create_result, thrd_success, "create blocking send thread");
394
395 shutdown(fds[1], SHUT_RD);
396
397 ASSERT_EQ(thrd_join(t, NULL), thrd_success, "join blocking send thread");
398
399 EXPECT_EQ(send_args.send_result, -1, "send should have returned -1");
400 EXPECT_EQ(send_args.send_errno, EPIPE, "send should have set errno to EPIPE");
401
402 END_TEST;
403 }
404
socketpair_clone_or_unwrap_and_wrap_test(void)405 bool socketpair_clone_or_unwrap_and_wrap_test(void) {
406 BEGIN_TEST;
407
408 int fds[2];
409 int status = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
410 ASSERT_EQ(status, 0, "socketpair(AF_UNIX, SOCK_STREAM, 0, fds) failed");
411
412 zx_handle_t handles[FDIO_MAX_HANDLES];
413 uint32_t types[FDIO_MAX_HANDLES];
414 zx_status_t handle_count = fdio_clone_fd(fds[0], fds[0], handles, types);
415 ASSERT_GT(handle_count, 0, "fdio_clone_fd() failed");
416 EXPECT_EQ(PA_HND_TYPE(types[0]), PA_FDIO_SOCKET, "Wrong cloned fd type");
417
418 int cloned_fd = -1;
419 status = fdio_create_fd(handles, types, handle_count, &cloned_fd);
420 EXPECT_EQ(status, 0, "fdio_create_fd(..., &cloned_fd) failed");
421
422 handle_count = fdio_transfer_fd(fds[0], fds[0], handles, types);
423 ASSERT_GT(handle_count, 0, "fdio_transfer_fd() failed");
424 EXPECT_EQ(PA_HND_TYPE(types[0]), PA_FDIO_SOCKET, "Wrong transferred fd type");
425
426 int transferred_fd = -1;
427 status = fdio_create_fd(handles, types, handle_count, &transferred_fd);
428 EXPECT_EQ(status, 0, "fdio_create_fd(..., &transferred_fd) failed");
429
430 // Verify that an operation specific to socketpairs works on these fds.
431 ASSERT_EQ(shutdown(cloned_fd, SHUT_RD), 0, "shutdown(cloned_fd, SHUT_RD) failed");
432 ASSERT_EQ(shutdown(transferred_fd, SHUT_WR), 0, "shutdown(transferred_fd, SHUT_WR) failed");
433
434 if (cloned_fd != -1)
435 ASSERT_EQ(close(cloned_fd), 0, "Failed to close cloned_fd");
436 if (transferred_fd != -1)
437 ASSERT_EQ(close(transferred_fd), 0, "Failed to close transferred_fd");
438
439 END_TEST;
440 }
441
442 // Verify scenario, where multi-segment recvmsg is requested, but the socket has
443 // just enough data to *completely* fill one segment.
444 // In this scenario, an attempt to read data for the next segment immediately
445 // fails with ZX_ERR_SHOULD_WAIT; at this point recvmsg should report total
446 // number of bytes read, instead of failing with EAGAIN.
socketpair_recvmsg_nonblock_boundary_test(void)447 bool socketpair_recvmsg_nonblock_boundary_test(void) {
448 BEGIN_TEST;
449
450 int fds[2];
451 int status = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
452 ASSERT_EQ(status, 0, "socketpair(AF_UNIX, SOCK_STREAM, 0, fds) failed");
453
454 ASSERT_EQ(fcntl(fds[0], F_SETFL, O_NONBLOCK), 0, "");
455 ASSERT_EQ(fcntl(fds[1], F_SETFL, O_NONBLOCK), 0, "");
456
457 // Write 4 bytes of data to socket.
458 size_t actual;
459 const uint32_t data_out = 0x12345678;
460 EXPECT_EQ((ssize_t)sizeof(data_out), write(fds[0], &data_out, sizeof(data_out)), "Socket write failed");
461
462 uint32_t data_in1, data_in2;
463 // Fail at compilation stage if anyone changes types.
464 // This is mandatory here: we need the first chunk to be exactly the same
465 // length as total size of data we just wrote.
466 assert(sizeof(data_in1) == sizeof(data_out));
467
468 struct iovec iov[2];
469 iov[0].iov_base = &data_in1;
470 iov[0].iov_len = sizeof(data_in1);
471 iov[1].iov_base = &data_in2;
472 iov[1].iov_len = sizeof(data_in2);
473
474 struct msghdr msg;
475 msg.msg_name = NULL;
476 msg.msg_namelen = 0;
477 msg.msg_iov = iov;
478 msg.msg_iovlen = sizeof(iov) / sizeof(*iov);
479 msg.msg_control = NULL;
480 msg.msg_controllen = 0;
481 msg.msg_flags = 0;
482
483 actual = recvmsg(fds[1], &msg, 0);
484 EXPECT_EQ(sizeof(data_in1), actual, "Socket read failed");
485
486 close(fds[0]);
487 close(fds[1]);
488
489 END_TEST;
490 }
491
492 // Verify scenario, where multi-segment sendmsg is requested, but the socket has
493 // just enough spare buffer to *completely* read one segment.
494 // In this scenario, an attempt to send second segment should immediately fail
495 // with ZX_ERR_SHOULD_WAIT, but the sendmsg should report first segment length
496 // rather than failing with EAGAIN.
socketpair_sendmsg_nonblock_boundary_test(void)497 bool socketpair_sendmsg_nonblock_boundary_test(void) {
498 BEGIN_TEST;
499
500 const ssize_t memlength = 65536;
501 void* memchunk = malloc(memlength);
502
503 struct iovec iov[2];
504 iov[0].iov_base = memchunk;
505 iov[0].iov_len = memlength;
506 iov[1].iov_base = memchunk;
507 iov[1].iov_len = memlength;
508
509 int fds[2];
510 int status = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
511 ASSERT_EQ(status, 0, "socketpair(AF_UNIX, SOCK_STREAM, 0, fds) failed");
512
513 ASSERT_EQ(fcntl(fds[0], F_SETFL, O_NONBLOCK), 0, "");
514 ASSERT_EQ(fcntl(fds[1], F_SETFL, O_NONBLOCK), 0, "");
515
516 struct msghdr msg;
517 msg.msg_name = NULL;
518 msg.msg_namelen = 0;
519 msg.msg_iov = iov;
520 msg.msg_iovlen = sizeof(iov) / sizeof(*iov);
521 msg.msg_control = NULL;
522 msg.msg_controllen = 0;
523 msg.msg_flags = 0;
524
525 // 1. Keep sending data until socket is saturated.
526 while (sendmsg(fds[0], &msg, 0) > 0)
527 ;
528
529 // 2. Consume one segment of the data.
530 EXPECT_EQ(memlength, read(fds[1], memchunk, memlength), "Socket read failed.");
531
532 // 3. Push again 2 packets of <memlength> bytes, observe only one sent.
533 EXPECT_EQ(memlength, sendmsg(fds[0], &msg, 0),
534 "Partial sendmsg failed; is the socket buffer varying?");
535
536 close(fds[0]);
537 close(fds[1]);
538
539 free(memchunk);
540 END_TEST;
541 }
542
socketpair_wait_begin_end(void)543 bool socketpair_wait_begin_end(void) {
544 BEGIN_TEST;
545
546 int fds[2];
547 int status = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
548 ASSERT_EQ(status, 0, "socketpair(AF_UNIX, SOCK_STREAM, 0, fds) failed");
549
550 fdio_t* io = fdio_unsafe_fd_to_io(fds[0]);
551
552 // fdio_unsafe_wait_begin
553
554 zx_handle_t handle = ZX_HANDLE_INVALID;
555 zx_signals_t signals = ZX_SIGNAL_NONE;
556 fdio_unsafe_wait_begin(io, POLLIN, &handle, &signals);
557 EXPECT_NE(handle, ZX_HANDLE_INVALID, "");
558 EXPECT_EQ(signals, ZX_SOCKET_READABLE | ZX_SOCKET_PEER_CLOSED | ZX_SOCKET_PEER_WRITE_DISABLED, "");
559
560 handle = ZX_HANDLE_INVALID;
561 signals = ZX_SIGNAL_NONE;
562 fdio_unsafe_wait_begin(io, POLLOUT, &handle, &signals);
563 EXPECT_NE(handle, ZX_HANDLE_INVALID, "");
564 EXPECT_EQ(signals, ZX_SOCKET_WRITABLE | ZX_SOCKET_WRITE_DISABLED, "");
565
566 handle = ZX_HANDLE_INVALID;
567 signals = ZX_SIGNAL_NONE;
568 fdio_unsafe_wait_begin(io, POLLRDHUP, &handle, &signals);
569 EXPECT_NE(handle, ZX_HANDLE_INVALID, "");
570 EXPECT_EQ(signals, ZX_SOCKET_PEER_CLOSED | ZX_SOCKET_PEER_WRITE_DISABLED, "");
571
572 // fdio_unsafe_wait_end
573
574 uint32_t events = 0u;
575 fdio_unsafe_wait_end(io, ZX_SOCKET_READABLE, &events);
576 EXPECT_EQ(events, (uint32_t)POLLIN, "");
577
578 events = 0u;
579 fdio_unsafe_wait_end(io, ZX_SOCKET_PEER_CLOSED, &events);
580 EXPECT_EQ(events, (uint32_t)(POLLIN | POLLRDHUP), "");
581
582 events = 0u;
583 fdio_unsafe_wait_end(io, ZX_SOCKET_PEER_WRITE_DISABLED, &events);
584 EXPECT_EQ(events, (uint32_t)(POLLIN | POLLRDHUP), "");
585
586 events = 0u;
587 fdio_unsafe_wait_end(io, ZX_SOCKET_WRITABLE, &events);
588 EXPECT_EQ(events, (uint32_t)POLLOUT, "");
589
590 events = 0u;
591 fdio_unsafe_wait_end(io, ZX_SOCKET_WRITE_DISABLED, &events);
592 EXPECT_EQ(events, (uint32_t)POLLOUT, "");
593
594 fdio_unsafe_release(io);
595 close(fds[0]);
596 close(fds[1]);
597
598 END_TEST;
599 }
600
601 BEGIN_TEST_CASE(fdio_socketpair_test)
602 RUN_TEST(socketpair_test);
603 RUN_TEST(socketpair_shutdown_rd_test);
604 RUN_TEST(socketpair_shutdown_wr_test);
605 RUN_TEST(socketpair_shutdown_rdwr_test);
606 RUN_TEST(socketpair_shutdown_self_wr_poll_test);
607 RUN_TEST(socketpair_shutdown_peer_wr_poll_test);
608 RUN_TEST(socketpair_shutdown_self_rd_during_recv_test);
609 RUN_TEST(socketpair_shutdown_peer_wr_during_recv_test);
610 RUN_TEST(socketpair_shutdown_self_wr_during_send_test);
611 RUN_TEST(socketpair_shutdown_peer_rd_during_send_test);
612 RUN_TEST(socketpair_clone_or_unwrap_and_wrap_test);
613 RUN_TEST(socketpair_recvmsg_nonblock_boundary_test);
614 RUN_TEST(socketpair_sendmsg_nonblock_boundary_test);
615 RUN_TEST(socketpair_wait_begin_end);
616 END_TEST_CASE(fdio_socketpair_test)
617