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 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 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 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 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 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