xref: /xnu-8019.80.24/tests/poll.c (revision a325d9c4a84054e40bbe985afedcb50ab80993ea)
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