| 1 | #include <darwintest.h> |
| 2 | #include <poll.h> |
| 3 | #include <sys/socket.h> |
| 4 | #include <unistd.h> |
| 5 | |
| 6 | T_GLOBAL_META(T_META_RUN_CONCURRENTLY(true)); |
| 7 | |
| 8 | T_DECL(socket_poll_close_25786011, "Tests an invalid poll call to a socket and then calling close.", T_META_LTEPHASE(LTE_POSTINIT)) |
| 9 | { |
| 10 | int my_socket, ret; |
| 11 | |
| 12 | my_socket = socket(PF_LOCAL, SOCK_STREAM, 0); |
| 13 | T_WITH_ERRNO; T_ASSERT_TRUE(my_socket > 0, "create socket"); |
| 14 | |
| 15 | /* |
| 16 | * Setup a pollfd that we know will return an error when we try |
| 17 | * to create a knote for it. We specify a BSD vnode specific event |
| 18 | * for a socket. |
| 19 | */ |
| 20 | struct pollfd my_pollfd = { |
| 21 | .fd = my_socket, |
| 22 | .events = POLLEXTEND |
| 23 | }; |
| 24 | |
| 25 | /* |
| 26 | * Previously the call to kevent_register() in the kernel from this call |
| 27 | * would leak an iocount reference on the fileproc, which would cause any |
| 28 | * subsequent calls to close() on the associated fd to block indefinitely. |
| 29 | */ |
| 30 | ret = poll(&my_pollfd, 1, 0); |
| 31 | T_WITH_ERRNO; T_ASSERT_TRUE(ret == 1, "poll returned %d", ret); |
| 32 | |
| 33 | ret = close(my_socket); |
| 34 | T_ASSERT_POSIX_ZERO(ret, "close on socket with fd %d\n", my_socket); |
| 35 | |
| 36 | T_PASS("socket_poll_close_25786011 PASSED"); |
| 37 | } |