1 /*
2 * Rudimentary test suite used while implementing pselect(2).
3 */
4
5 #include <assert.h>
6 #include <errno.h>
7 #include <signal.h>
8 #include <stdio.h>
9 #include <string.h>
10 #include <unistd.h>
11
12
13 static int alarm_flag = 0;
14
15
16 static void
nop(int signo)17 nop(int signo)
18 {
19 }
20
21
22 static void
set_alarm_flag(int signo)23 set_alarm_flag(int signo)
24 {
25 alarm_flag = 1;
26 }
27
28
29
30 /*
31 * Very roughly exercise pselect(2).
32 */
33
34 static void
test_pselect()35 test_pselect()
36 {
37 fd_set rset;
38 fd_set wset;
39 sigset_t blockset;
40 struct timespec timeout;
41 int des[2];
42 int r;
43 char buf[1];
44
45 printf("test_pselect\n");
46
47 /*
48 * It is always possible to write to stdout (if not redirected).
49 */
50
51 FD_ZERO(&wset);
52 FD_SET(1, &wset);
53
54 r = pselect(2, NULL, &wset, NULL, NULL, NULL);
55 assert(r == 1);
56 assert(FD_ISSET(1, &wset));
57
58 /*
59 * Write to a pipe and check a select on the read end does not block.
60 */
61
62 r = pipe(des);
63 assert(r == 0);
64
65 FD_ZERO(&rset);
66 FD_SET(des[0], &rset);
67
68 buf[0] = 'f';
69 r = write(des[1], buf, 1);
70 assert(r == 1);
71
72 r = pselect(des[0]+1, &rset, NULL, NULL, NULL, NULL);
73 assert(r == 1);
74 assert(FD_ISSET(des[0], &rset));
75
76 r = read(des[0], buf, 1);
77 assert(r == 1);
78 assert(buf[0] == 'f');
79
80 /*
81 * Block until signal reception.
82 */
83
84 signal(SIGALRM, nop);
85 alarm(1);
86
87 FD_ZERO(&rset);
88 FD_SET(des[0], &rset);
89
90 r = pselect(des[0]+1, &rset, NULL, NULL, NULL, NULL);
91 assert(r == -1);
92 assert(errno == EINTR);
93
94 /*
95 * Block until timeout.
96 */
97
98 FD_ZERO(&rset);
99 FD_SET(des[0], &rset);
100
101 timeout.tv_sec = 1;
102 timeout.tv_nsec = 0;
103 r = pselect(des[0]+1, &rset, NULL, NULL, &timeout, NULL);
104 assert(r == 0);
105
106 /*
107 * When the timeout is zero, the call should not block.
108 */
109
110 timeout.tv_sec = 0;
111 timeout.tv_nsec = 0;
112 FD_ZERO(&rset);
113 FD_SET(des[0], &rset);
114
115 r = pselect(des[0]+1, &rset, NULL, NULL, &timeout, NULL);
116 assert(r == 0);
117
118 /*
119 * When a signal is masked, the syscall is not interrupted and the
120 * signal is received on completion.
121 */
122
123 sigemptyset(&blockset);
124 sigaddset(&blockset, SIGALRM);
125
126 signal(SIGALRM, set_alarm_flag);
127 alarm(1);
128
129 timeout.tv_sec = 2;
130 timeout.tv_nsec = 0;
131 r = pselect(des[0]+1, &rset, NULL, NULL, &timeout, &blockset);
132 assert(r == 0);
133 assert(alarm_flag);
134
135 close(des[0]);
136 close(des[1]);
137 }
138
139
140 int
main(void)141 main(void)
142 {
143 test_pselect();
144 return (0);
145 }
146