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