]>
git.saurik.com Git - apple/xnu.git/blob - tests/poll.c
4 #include <darwintest.h>
6 #include <dispatch/dispatch.h>
13 T_GLOBAL_META(T_META_NAMESPACE("xnu.poll"),
14 T_META_RUN_CONCURRENTLY(true));
16 #define SLEEP_TIME_SECS 1
17 #define POLL_TIMEOUT_MS 1800
18 static_assert(POLL_TIMEOUT_MS
> (SLEEP_TIME_SECS
* 1000),
19 "poll timeout should be longer than sleep time");
22 * This matches the behavior of other UNIXes, but is under-specified in POSIX.
24 * See <rdar://problem/28372390>.
26 T_DECL(sleep_with_no_fds
,
27 "poll() called with no fds provided should act like sleep")
29 uint64_t begin_time
, sleep_time
, poll_time
;
30 struct pollfd pfd
= { .fd
= 0, .events
= 0, .revents
= 0 };
32 begin_time
= mach_absolute_time();
33 sleep(SLEEP_TIME_SECS
);
34 sleep_time
= mach_absolute_time() - begin_time
;
35 T_LOG("sleep(%d) ~= %llu mach absolute time units", SLEEP_TIME_SECS
, sleep_time
);
37 begin_time
= mach_absolute_time();
38 T_ASSERT_POSIX_SUCCESS(poll(&pfd
, 0, POLL_TIMEOUT_MS
),
39 "poll() with 0 events and timeout %d ms", POLL_TIMEOUT_MS
);
40 poll_time
= mach_absolute_time() - begin_time
;
42 T_EXPECT_GT(poll_time
, sleep_time
,
43 "poll(... %d) should wait longer than sleep(1)", POLL_TIMEOUT_MS
);
46 #define LAUNCHD_PATH "/sbin/launchd"
47 #define PIPE_DIR_TIMEOUT_SECS 1
50 * See <rdar://problem/28539155>.
53 "poll() with directories should return an error")
55 int file
, dir
, pipes
[2];
56 struct pollfd pfd
[] = {
62 file
= open(LAUNCHD_PATH
, O_RDONLY
| O_NONBLOCK
);
63 T_QUIET
; T_ASSERT_POSIX_SUCCESS(file
, "open(%s)", LAUNCHD_PATH
);
64 dir
= open(".", O_RDONLY
| O_NONBLOCK
);
65 T_QUIET
; T_ASSERT_POSIX_SUCCESS(dir
, "open(\".\")");
66 T_QUIET
; T_ASSERT_POSIX_SUCCESS(pipe(pipes
), NULL
);
70 T_EXPECT_POSIX_SUCCESS(poll(pfd
, 1, -1), "poll() with a directory");
71 T_QUIET
; T_EXPECT_TRUE(pfd
[0].revents
& POLLNVAL
,
72 "directory should be an invalid event");
74 /* file and directory */
75 pfd
[0].fd
= file
; pfd
[0].revents
= 0;
76 pfd
[1].fd
= dir
; pfd
[1].revents
= 0;
77 T_EXPECT_POSIX_SUCCESS(poll(pfd
, 2, -1),
78 "poll() with a file and directory");
79 T_QUIET
; T_EXPECT_TRUE(pfd
[0].revents
& POLLIN
, "file should be readable");
80 T_QUIET
; T_EXPECT_TRUE(pfd
[1].revents
& POLLNVAL
,
81 "directory should be an invalid event");
83 /* directory and file */
84 pfd
[0].fd
= dir
; pfd
[0].revents
= 0;
85 pfd
[1].fd
= file
; pfd
[1].revents
= 0;
86 T_EXPECT_POSIX_SUCCESS(poll(pfd
, 2, -1),
87 "poll() with a directory and a file");
88 T_QUIET
; T_EXPECT_TRUE(pfd
[0].revents
& POLLNVAL
,
89 "directory should be an invalid event");
90 T_QUIET
; T_EXPECT_TRUE(pfd
[1].revents
& POLLIN
, "file should be readable");
93 pfd
[0].fd
= file
; pfd
[0].revents
= 0;
94 pfd
[1].fd
= pipes
[0]; pfd
[0].revents
= 0;
95 T_EXPECT_POSIX_SUCCESS(poll(pfd
, 2, -1),
96 "poll() with a file and pipe");
97 T_QUIET
; T_EXPECT_TRUE(pfd
[0].revents
& POLLIN
, "file should be readable");
98 T_QUIET
; T_EXPECT_FALSE(pfd
[1].revents
& POLLIN
,
99 "pipe should not be readable");
101 /* file, directory, and pipe */
102 pfd
[0].fd
= file
; pfd
[0].revents
= 0;
103 pfd
[1].fd
= dir
; pfd
[1].revents
= 0;
104 pfd
[2].fd
= pipes
[0]; pfd
[2].revents
= 0;
105 T_EXPECT_POSIX_SUCCESS(poll(pfd
, 3, -1),
106 "poll() with a file, directory, and pipe");
107 T_QUIET
; T_EXPECT_TRUE(pfd
[0].revents
& POLLIN
, "file should be readable");
108 T_QUIET
; T_EXPECT_TRUE(pfd
[1].revents
& POLLNVAL
,
109 "directory should be an invalid event");
110 T_QUIET
; T_EXPECT_FALSE(pfd
[2].revents
& POLLIN
, "pipe should not be readable");
112 /* directory and pipe */
113 __block
bool timed_out
= true;
114 pfd
[0].fd
= dir
; pfd
[0].revents
= 0;
115 pfd
[1].fd
= pipes
[0]; pfd
[1].revents
= 0;
116 dispatch_after(dispatch_time(DISPATCH_TIME_NOW
,
117 PIPE_DIR_TIMEOUT_SECS
* NSEC_PER_SEC
),
118 dispatch_get_global_queue(QOS_CLASS_DEFAULT
, 0), ^{
119 T_ASSERT_FALSE(timed_out
, "poll timed out after %d seconds",
120 PIPE_DIR_TIMEOUT_SECS
);
123 T_EXPECT_POSIX_SUCCESS(poll(pfd
, 3, -1),
124 "poll() with a directory and pipe");
127 T_QUIET
; T_EXPECT_TRUE(pfd
[0].revents
& POLLNVAL
,
128 "directory should be an invalid event");
129 T_QUIET
; T_EXPECT_FALSE(pfd
[1].revents
& POLLIN
, "pipe should not be readable");