1*a325d9c4SApple OSS Distributions #ifdef T_NAMESPACE 2*a325d9c4SApple OSS Distributions #undef T_NAMESPACE 3*a325d9c4SApple OSS Distributions #endif 4*a325d9c4SApple OSS Distributions #include <darwintest.h> 5*a325d9c4SApple OSS Distributions 6*a325d9c4SApple OSS Distributions #include <dispatch/dispatch.h> 7*a325d9c4SApple OSS Distributions #include <fcntl.h> 8*a325d9c4SApple OSS Distributions #include <mach/mach.h> 9*a325d9c4SApple OSS Distributions #include <poll.h> 10*a325d9c4SApple OSS Distributions #include <stdint.h> 11*a325d9c4SApple OSS Distributions #include <unistd.h> 12*a325d9c4SApple OSS Distributions 13*a325d9c4SApple OSS Distributions T_GLOBAL_META(T_META_NAMESPACE("xnu.poll"), 14*a325d9c4SApple OSS Distributions T_META_RUN_CONCURRENTLY(true)); 15*a325d9c4SApple OSS Distributions 16*a325d9c4SApple OSS Distributions #define SLEEP_TIME_SECS 1 17*a325d9c4SApple OSS Distributions #define POLL_TIMEOUT_MS 1800 18*a325d9c4SApple OSS Distributions static_assert(POLL_TIMEOUT_MS > (SLEEP_TIME_SECS * 1000), 19*a325d9c4SApple OSS Distributions "poll timeout should be longer than sleep time"); 20*a325d9c4SApple OSS Distributions 21*a325d9c4SApple OSS Distributions /* 22*a325d9c4SApple OSS Distributions * This matches the behavior of other UNIXes, but is under-specified in POSIX. 23*a325d9c4SApple OSS Distributions * 24*a325d9c4SApple OSS Distributions * See <rdar://problem/28372390>. 25*a325d9c4SApple OSS Distributions */ 26*a325d9c4SApple OSS Distributions T_DECL(sleep_with_no_fds, 27*a325d9c4SApple OSS Distributions "poll() called with no fds provided should act like sleep") 28*a325d9c4SApple OSS Distributions { 29*a325d9c4SApple OSS Distributions uint64_t begin_time, sleep_time, poll_time; 30*a325d9c4SApple OSS Distributions struct pollfd pfd = { .fd = 0, .events = 0, .revents = 0 }; 31*a325d9c4SApple OSS Distributions 32*a325d9c4SApple OSS Distributions begin_time = mach_absolute_time(); 33*a325d9c4SApple OSS Distributions sleep(SLEEP_TIME_SECS); 34*a325d9c4SApple OSS Distributions sleep_time = mach_absolute_time() - begin_time; 35*a325d9c4SApple OSS Distributions T_LOG("sleep(%d) ~= %llu mach absolute time units", SLEEP_TIME_SECS, sleep_time); 36*a325d9c4SApple OSS Distributions 37*a325d9c4SApple OSS Distributions begin_time = mach_absolute_time(); 38*a325d9c4SApple OSS Distributions T_ASSERT_POSIX_SUCCESS(poll(&pfd, 0, POLL_TIMEOUT_MS), 39*a325d9c4SApple OSS Distributions "poll() with 0 events and timeout %d ms", POLL_TIMEOUT_MS); 40*a325d9c4SApple OSS Distributions poll_time = mach_absolute_time() - begin_time; 41*a325d9c4SApple OSS Distributions 42*a325d9c4SApple OSS Distributions T_EXPECT_GT(poll_time, sleep_time, 43*a325d9c4SApple OSS Distributions "poll(... %d) should wait longer than sleep(1)", POLL_TIMEOUT_MS); 44*a325d9c4SApple OSS Distributions } 45*a325d9c4SApple OSS Distributions 46*a325d9c4SApple OSS Distributions #define LAUNCHD_PATH "/sbin/launchd" 47*a325d9c4SApple OSS Distributions #define PIPE_DIR_TIMEOUT_SECS 1 48*a325d9c4SApple OSS Distributions 49*a325d9c4SApple OSS Distributions /* 50*a325d9c4SApple OSS Distributions * See <rdar://problem/28539155>. 51*a325d9c4SApple OSS Distributions */ 52*a325d9c4SApple OSS Distributions T_DECL(directories, 53*a325d9c4SApple OSS Distributions "poll() with directories should return an error") 54*a325d9c4SApple OSS Distributions { 55*a325d9c4SApple OSS Distributions int file, dir, pipes[2]; 56*a325d9c4SApple OSS Distributions struct pollfd pfd[] = { 57*a325d9c4SApple OSS Distributions { .events = POLLIN }, 58*a325d9c4SApple OSS Distributions { .events = POLLIN }, 59*a325d9c4SApple OSS Distributions { .events = POLLIN }, 60*a325d9c4SApple OSS Distributions }; 61*a325d9c4SApple OSS Distributions 62*a325d9c4SApple OSS Distributions file = open(LAUNCHD_PATH, O_RDONLY | O_NONBLOCK); 63*a325d9c4SApple OSS Distributions T_QUIET; T_ASSERT_POSIX_SUCCESS(file, "open(%s)", LAUNCHD_PATH); 64*a325d9c4SApple OSS Distributions dir = open(".", O_RDONLY | O_NONBLOCK); 65*a325d9c4SApple OSS Distributions T_QUIET; T_ASSERT_POSIX_SUCCESS(dir, "open(\".\")"); 66*a325d9c4SApple OSS Distributions T_QUIET; T_ASSERT_POSIX_SUCCESS(pipe(pipes), NULL); 67*a325d9c4SApple OSS Distributions 68*a325d9c4SApple OSS Distributions /* just directory */ 69*a325d9c4SApple OSS Distributions pfd[0].fd = dir; 70*a325d9c4SApple OSS Distributions T_EXPECT_POSIX_SUCCESS(poll(pfd, 1, -1), "poll() with a directory"); 71*a325d9c4SApple OSS Distributions T_QUIET; T_EXPECT_TRUE(pfd[0].revents & POLLNVAL, 72*a325d9c4SApple OSS Distributions "directory should be an invalid event"); 73*a325d9c4SApple OSS Distributions 74*a325d9c4SApple OSS Distributions /* file and directory */ 75*a325d9c4SApple OSS Distributions pfd[0].fd = file; pfd[0].revents = 0; 76*a325d9c4SApple OSS Distributions pfd[1].fd = dir; pfd[1].revents = 0; 77*a325d9c4SApple OSS Distributions T_EXPECT_POSIX_SUCCESS(poll(pfd, 2, -1), 78*a325d9c4SApple OSS Distributions "poll() with a file and directory"); 79*a325d9c4SApple OSS Distributions T_QUIET; T_EXPECT_TRUE(pfd[0].revents & POLLIN, "file should be readable"); 80*a325d9c4SApple OSS Distributions T_QUIET; T_EXPECT_TRUE(pfd[1].revents & POLLNVAL, 81*a325d9c4SApple OSS Distributions "directory should be an invalid event"); 82*a325d9c4SApple OSS Distributions 83*a325d9c4SApple OSS Distributions /* directory and file */ 84*a325d9c4SApple OSS Distributions pfd[0].fd = dir; pfd[0].revents = 0; 85*a325d9c4SApple OSS Distributions pfd[1].fd = file; pfd[1].revents = 0; 86*a325d9c4SApple OSS Distributions T_EXPECT_POSIX_SUCCESS(poll(pfd, 2, -1), 87*a325d9c4SApple OSS Distributions "poll() with a directory and a file"); 88*a325d9c4SApple OSS Distributions T_QUIET; T_EXPECT_TRUE(pfd[0].revents & POLLNVAL, 89*a325d9c4SApple OSS Distributions "directory should be an invalid event"); 90*a325d9c4SApple OSS Distributions T_QUIET; T_EXPECT_TRUE(pfd[1].revents & POLLIN, "file should be readable"); 91*a325d9c4SApple OSS Distributions 92*a325d9c4SApple OSS Distributions /* file and pipe */ 93*a325d9c4SApple OSS Distributions pfd[0].fd = file; pfd[0].revents = 0; 94*a325d9c4SApple OSS Distributions pfd[1].fd = pipes[0]; pfd[0].revents = 0; 95*a325d9c4SApple OSS Distributions T_EXPECT_POSIX_SUCCESS(poll(pfd, 2, -1), 96*a325d9c4SApple OSS Distributions "poll() with a file and pipe"); 97*a325d9c4SApple OSS Distributions T_QUIET; T_EXPECT_TRUE(pfd[0].revents & POLLIN, "file should be readable"); 98*a325d9c4SApple OSS Distributions T_QUIET; T_EXPECT_FALSE(pfd[1].revents & POLLIN, 99*a325d9c4SApple OSS Distributions "pipe should not be readable"); 100*a325d9c4SApple OSS Distributions 101*a325d9c4SApple OSS Distributions /* file, directory, and pipe */ 102*a325d9c4SApple OSS Distributions pfd[0].fd = file; pfd[0].revents = 0; 103*a325d9c4SApple OSS Distributions pfd[1].fd = dir; pfd[1].revents = 0; 104*a325d9c4SApple OSS Distributions pfd[2].fd = pipes[0]; pfd[2].revents = 0; 105*a325d9c4SApple OSS Distributions T_EXPECT_POSIX_SUCCESS(poll(pfd, 3, -1), 106*a325d9c4SApple OSS Distributions "poll() with a file, directory, and pipe"); 107*a325d9c4SApple OSS Distributions T_QUIET; T_EXPECT_TRUE(pfd[0].revents & POLLIN, "file should be readable"); 108*a325d9c4SApple OSS Distributions T_QUIET; T_EXPECT_TRUE(pfd[1].revents & POLLNVAL, 109*a325d9c4SApple OSS Distributions "directory should be an invalid event"); 110*a325d9c4SApple OSS Distributions T_QUIET; T_EXPECT_FALSE(pfd[2].revents & POLLIN, "pipe should not be readable"); 111*a325d9c4SApple OSS Distributions 112*a325d9c4SApple OSS Distributions /* directory and pipe */ 113*a325d9c4SApple OSS Distributions __block bool timed_out = true; 114*a325d9c4SApple OSS Distributions pfd[0].fd = dir; pfd[0].revents = 0; 115*a325d9c4SApple OSS Distributions pfd[1].fd = pipes[0]; pfd[1].revents = 0; 116*a325d9c4SApple OSS Distributions dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 117*a325d9c4SApple OSS Distributions PIPE_DIR_TIMEOUT_SECS * NSEC_PER_SEC), 118*a325d9c4SApple OSS Distributions dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^{ 119*a325d9c4SApple OSS Distributions T_ASSERT_FALSE(timed_out, "poll timed out after %d seconds", 120*a325d9c4SApple OSS Distributions PIPE_DIR_TIMEOUT_SECS); 121*a325d9c4SApple OSS Distributions }); 122*a325d9c4SApple OSS Distributions 123*a325d9c4SApple OSS Distributions T_EXPECT_POSIX_SUCCESS(poll(pfd, 3, -1), 124*a325d9c4SApple OSS Distributions "poll() with a directory and pipe"); 125*a325d9c4SApple OSS Distributions timed_out = false; 126*a325d9c4SApple OSS Distributions 127*a325d9c4SApple OSS Distributions T_QUIET; T_EXPECT_TRUE(pfd[0].revents & POLLNVAL, 128*a325d9c4SApple OSS Distributions "directory should be an invalid event"); 129*a325d9c4SApple OSS Distributions T_QUIET; T_EXPECT_FALSE(pfd[1].revents & POLLIN, "pipe should not be readable"); 130*a325d9c4SApple OSS Distributions } 131