1 /*-
2 * Copyright (c) 2004 Robert N. M. Watson
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27 #include <sys/types.h>
28 #include <sys/event.h>
29 #include <sys/socket.h>
30 #include <sys/time.h>
31
32 #include <errno.h>
33 #include <fcntl.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <unistd.h>
38
39 static int curtest = 1;
40
41 /*-
42 * This test uses UNIX domain socket pairs to perform some basic exercising
43 * of kqueue functionality on sockets. In particular, testing that for read
44 * and write filters, we see the correct detection of whether reads and
45 * writes should actually be able to occur.
46 *
47 * TODO:
48 * - Test read/write filters for listen/accept sockets.
49 * - Handle the XXXRW below regarding datagram sockets.
50 * - Test that watermark/buffer size "data" fields returned by kqueue are
51 * correct.
52 * - Check that kqueue does something sensible when the remote endpoing is
53 * closed.
54 */
55
56 #define OK(testname) printf("ok %d - %s\n", curtest, testname); \
57 curtest++;
58
59 static void
fail(int error,const char * func,const char * socktype,const char * rest)60 fail(int error, const char *func, const char *socktype, const char *rest)
61 {
62
63 printf("not ok %d\n", curtest);
64
65 if (socktype == NULL)
66 printf("# %s(): %s\n", func, strerror(error));
67 else if (rest == NULL)
68 printf("# %s(%s): %s\n", func, socktype,
69 strerror(error));
70 else
71 printf("# %s(%s, %s): %s\n", func, socktype, rest,
72 strerror(error));
73 exit(-1);
74 }
75
76 static void
fail_assertion(const char * func,const char * socktype,const char * rest,const char * assertion)77 fail_assertion(const char *func, const char *socktype, const char *rest,
78 const char *assertion)
79 {
80
81 printf("not ok %d - %s\n", curtest, assertion);
82
83 if (socktype == NULL)
84 printf("# %s(): assertion %s failed\n", func,
85 assertion);
86 else if (rest == NULL)
87 printf("# %s(%s): assertion %s failed\n", func,
88 socktype, assertion);
89 else
90 printf("# %s(%s, %s): assertion %s failed\n", func,
91 socktype, rest, assertion);
92 exit(-1);
93 }
94
95 /*
96 * Test read kevent on a socket pair: check to make sure endpoint 0 isn't
97 * readable when we start, then write to endpoint 1 and confirm that endpoint
98 * 0 is now readable. Drain the write, then check that it's not readable
99 * again. Use non-blocking kqueue operations and socket operations.
100 */
101 static void
test_evfilt_read(int kq,int fd[2],const char * socktype)102 test_evfilt_read(int kq, int fd[2], const char *socktype)
103 {
104 struct timespec ts;
105 struct kevent ke;
106 ssize_t len;
107 char ch;
108 int i;
109
110 EV_SET(&ke, fd[0], EVFILT_READ, EV_ADD, 0, 0, NULL);
111 if (kevent(kq, &ke, 1, NULL, 0, NULL) == -1)
112 fail(errno, "kevent", socktype, "EVFILT_READ, EV_ADD");
113 OK("EVFILT_READ, EV_ADD");
114
115 /*
116 * Confirm not readable to begin with, no I/O yet.
117 */
118 ts.tv_sec = 0;
119 ts.tv_nsec = 0;
120 i = kevent(kq, NULL, 0, &ke, 1, &ts);
121 if (i == -1)
122 fail(errno, "kevent", socktype, "EVFILT_READ");
123 OK("EVFILT_READ");
124 if (i != 0)
125 fail_assertion("kevent", socktype, "EVFILT_READ",
126 "empty socket unreadable");
127 OK("empty socket unreadable");
128
129 /*
130 * Write a byte to one end.
131 */
132 ch = 'a';
133 len = write(fd[1], &ch, sizeof(ch));
134 if (len == -1)
135 fail(errno, "write", socktype, NULL);
136 OK("write one byte");
137 if (len != sizeof(ch))
138 fail_assertion("write", socktype, NULL, "write length");
139 OK("write one byte length");
140
141 /*
142 * Other end should now be readable.
143 */
144 ts.tv_sec = 0;
145 ts.tv_nsec = 0;
146 i = kevent(kq, NULL, 0, &ke, 1, &ts);
147 if (i == -1)
148 fail(errno, "kevent", socktype, "EVFILT_READ");
149 OK("EVFILT_READ");
150 if (i != 1)
151 fail_assertion("kevent", socktype, "EVFILT_READ",
152 "non-empty socket unreadable");
153 OK("non-empty socket unreadable");
154
155 /*
156 * Read a byte to clear the readable state.
157 */
158 len = read(fd[0], &ch, sizeof(ch));
159 if (len == -1)
160 fail(errno, "read", socktype, NULL);
161 OK("read one byte");
162 if (len != sizeof(ch))
163 fail_assertion("read", socktype, NULL, "read length");
164 OK("read one byte length");
165
166 /*
167 * Now re-check for readability.
168 */
169 ts.tv_sec = 0;
170 ts.tv_nsec = 0;
171 i = kevent(kq, NULL, 0, &ke, 1, &ts);
172 if (i == -1)
173 fail(errno, "kevent", socktype, "EVFILT_READ");
174 OK("EVFILT_READ");
175 if (i != 0)
176 fail_assertion("kevent", socktype, "EVFILT_READ",
177 "empty socket unreadable");
178 OK("empty socket unreadable");
179
180 EV_SET(&ke, fd[0], EVFILT_READ, EV_DELETE, 0, 0, NULL);
181 if (kevent(kq, &ke, 1, NULL, 0, NULL) == -1)
182 fail(errno, "kevent", socktype, "EVFILT_READ, EV_DELETE");
183 OK("EVFILT_READ, EV_DELETE");
184 }
185
186 static void
test_evfilt_write(int kq,int fd[2],const char * socktype)187 test_evfilt_write(int kq, int fd[2], const char *socktype)
188 {
189 struct timespec ts;
190 struct kevent ke;
191 ssize_t len;
192 char ch;
193 int i;
194
195 EV_SET(&ke, fd[0], EVFILT_WRITE, EV_ADD, 0, 0, NULL);
196 if (kevent(kq, &ke, 1, NULL, 0, NULL) == -1)
197 fail(errno, "kevent", socktype, "EVFILT_WRITE, EV_ADD");
198 OK("EVFILE_WRITE, EV_ADD");
199
200 /*
201 * Confirm writable to begin with, no I/O yet.
202 */
203 ts.tv_sec = 0;
204 ts.tv_nsec = 0;
205 i = kevent(kq, NULL, 0, &ke, 1, &ts);
206 if (i == -1)
207 fail(errno, "kevent", socktype, "EVFILT_WRITE");
208 OK("EVFILE_WRITE");
209 if (i != 1)
210 fail_assertion("kevent", socktype, "EVFILT_WRITE",
211 "empty socket unwritable");
212 OK("empty socket unwritable");
213
214 /*
215 * Write bytes into the socket until we can't write anymore.
216 */
217 ch = 'a';
218 while ((len = write(fd[0], &ch, sizeof(ch))) == sizeof(ch)) {};
219 if (len == -1 && errno != EAGAIN && errno != ENOBUFS)
220 fail(errno, "write", socktype, NULL);
221 OK("write");
222 if (len != -1 && len != sizeof(ch))
223 fail_assertion("write", socktype, NULL, "write length");
224 OK("write length");
225
226 /*
227 * Check to make sure the socket is no longer writable.
228 */
229 ts.tv_sec = 0;
230 ts.tv_nsec = 0;
231 i = kevent(kq, NULL, 0, &ke, 1, &ts);
232 if (i == -1)
233 fail(errno, "kevent", socktype, "EVFILT_WRITE");
234 OK("EVFILT_WRITE");
235 if (i != 0)
236 fail_assertion("kevent", socktype, "EVFILT_WRITE",
237 "full socket writable");
238 OK("full socket writable");
239
240 EV_SET(&ke, fd[0], EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
241 if (kevent(kq, &ke, 1, NULL, 0, NULL) == -1)
242 fail(errno, "kevent", socktype, "EVFILT_WRITE, EV_DELETE");
243 OK("EVFILT_WRITE, EV_DELETE");
244 }
245
246 /*
247 * Basic registration exercise for kqueue(2). Create several types/brands of
248 * sockets, and confirm that we can register for various events on them.
249 */
250 int
main(void)251 main(void)
252 {
253 int kq, sv[2];
254
255 printf("1..49\n");
256
257 kq = kqueue();
258 if (kq == -1)
259 fail(errno, "kqueue", NULL, NULL);
260 OK("kqueue()");
261
262 /*
263 * Create a UNIX domain datagram socket, and attach/test/detach a
264 * read filter on it.
265 */
266 if (socketpair(PF_UNIX, SOCK_DGRAM, 0, sv) == -1)
267 fail(errno, "socketpair", "PF_UNIX, SOCK_DGRAM", NULL);
268 OK("socketpair() 1");
269
270 if (fcntl(sv[0], F_SETFL, O_NONBLOCK) != 0)
271 fail(errno, "fcntl", "PF_UNIX, SOCK_DGRAM", "O_NONBLOCK");
272 OK("fcntl() 1");
273 if (fcntl(sv[1], F_SETFL, O_NONBLOCK) != 0)
274 fail(errno, "fcntl", "PF_UNIX, SOCK_DGRAM", "O_NONBLOCK");
275 OK("fnctl() 2");
276
277 test_evfilt_read(kq, sv, "PF_UNIX, SOCK_DGRAM");
278
279 if (close(sv[0]) == -1)
280 fail(errno, "close", "PF_UNIX/SOCK_DGRAM", "sv[0]");
281 OK("close() 1");
282 if (close(sv[1]) == -1)
283 fail(errno, "close", "PF_UNIX/SOCK_DGRAM", "sv[1]");
284 OK("close() 2");
285
286 #if 0
287 /*
288 * XXXRW: We disable the write test in the case of datagram sockets,
289 * as kqueue can't tell when the remote socket receive buffer is
290 * full, whereas the UNIX domain socket implementation can tell and
291 * returns ENOBUFS.
292 */
293 /*
294 * Create a UNIX domain datagram socket, and attach/test/detach a
295 * write filter on it.
296 */
297 if (socketpair(PF_UNIX, SOCK_DGRAM, 0, sv) == -1)
298 fail(errno, "socketpair", "PF_UNIX, SOCK_DGRAM", NULL);
299
300 if (fcntl(sv[0], F_SETFL, O_NONBLOCK) != 0)
301 fail(errno, "fcntl", "PF_UNIX, SOCK_DGRAM", "O_NONBLOCK");
302 if (fcntl(sv[1], F_SETFL, O_NONBLOCK) != 0)
303 fail(errno, "fcntl", "PF_UNIX, SOCK_DGRAM", "O_NONBLOCK");
304
305 test_evfilt_write(kq, sv, "PF_UNIX, SOCK_DGRAM");
306
307 if (close(sv[0]) == -1)
308 fail(errno, "close", "PF_UNIX/SOCK_DGRAM", "sv[0]");
309 if (close(sv[1]) == -1)
310 fail(errno, "close", "PF_UNIX/SOCK_DGRAM", "sv[1]");
311 #endif
312
313 /*
314 * Create a UNIX domain stream socket, and attach/test/detach a
315 * read filter on it.
316 */
317 if (socketpair(PF_UNIX, SOCK_STREAM, 0, sv) == -1)
318 fail(errno, "socketpair", "PF_UNIX, SOCK_STREAM", NULL);
319 OK("socketpair() 2");
320
321 if (fcntl(sv[0], F_SETFL, O_NONBLOCK) != 0)
322 fail(errno, "fcntl", "PF_UNIX, SOCK_STREAM", "O_NONBLOCK");
323 OK("fcntl() 3");
324 if (fcntl(sv[1], F_SETFL, O_NONBLOCK) != 0)
325 fail(errno, "fcntl", "PF_UNIX, SOCK_STREAM", "O_NONBLOCK");
326 OK("fcntl() 4");
327
328 test_evfilt_read(kq, sv, "PF_UNIX, SOCK_STREAM");
329
330 if (close(sv[0]) == -1)
331 fail(errno, "close", "PF_UNIX/SOCK_STREAM", "sv[0]");
332 OK("close() 3");
333 if (close(sv[1]) == -1)
334 fail(errno, "close", "PF_UNIX/SOCK_STREAM", "sv[1]");
335 OK("close() 4");
336
337 /*
338 * Create a UNIX domain stream socket, and attach/test/detach a
339 * write filter on it.
340 */
341 if (socketpair(PF_UNIX, SOCK_STREAM, 0, sv) == -1)
342 fail(errno, "socketpair", "PF_UNIX, SOCK_STREAM", NULL);
343 OK("socketpair() 3");
344
345 if (fcntl(sv[0], F_SETFL, O_NONBLOCK) != 0)
346 fail(errno, "fcntl", "PF_UNIX, SOCK_STREAM", "O_NONBLOCK");
347 OK("fcntl() 5");
348 if (fcntl(sv[1], F_SETFL, O_NONBLOCK) != 0)
349 fail(errno, "fcntl", "PF_UNIX, SOCK_STREAM", "O_NONBLOCK");
350 OK("fcntl() 6");
351
352 test_evfilt_write(kq, sv, "PF_UNIX, SOCK_STREAM");
353
354 if (close(sv[0]) == -1)
355 fail(errno, "close", "PF_UNIX/SOCK_STREAM", "sv[0]");
356 OK("close() 5");
357 if (close(sv[1]) == -1)
358 fail(errno, "close", "PF_UNIX/SOCK_STREAM", "sv[1]");
359 OK("close() 6");
360
361 if (close(kq) == -1)
362 fail(errno, "close", "kq", NULL);
363 OK("close() 7");
364
365 return (0);
366 }
367