1 /*-
2 * Copyright (c) 2005 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/ioctl.h>
30 #include <sys/select.h>
31 #include <sys/stat.h>
32 #include <sys/time.h>
33
34 #include <err.h>
35 #include <errno.h>
36 #include <fcntl.h>
37 #include <limits.h>
38 #include <poll.h>
39 #include <signal.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <unistd.h>
44
45 /*
46 * Regression test to exercise POSIX fifo I/O.
47 *
48 * We test a number of aspect of behavior, including:
49 *
50 * - If there's no data to read, then for blocking fifos, we block, and for
51 * non-blocking, we return EAGAIN.
52 *
53 * - If we write ten bytes, ten bytes can be read, and they're the same
54 * bytes, in the same order.
55 *
56 * - If we write two batches of five bytes, we can read the same ten bytes in
57 * one read of ten bytes.
58 *
59 * - If we write ten bytes, we can read the same ten bytes in two reads of
60 * five bytes each.
61 *
62 * - If we over-fill a buffer (by writing 512k, which we take to be a large
63 * number above default buffer sizes), we block if there is no reader.
64 *
65 * - That once 512k (ish) is read from the other end, the blocked writer
66 * wakes up.
67 *
68 * - When a fifo is empty, poll, select, kqueue, and fionread report it is
69 * writable but not readable.
70 *
71 * - When a fifo has data in it, poll, select, and kqueue report that it is
72 * writable.
73 *
74 * - XXX: blocked reader semantics?
75 *
76 * - XXX: event behavior on remote close?
77 *
78 * Although behavior of O_RDWR isn't defined for fifos by POSIX, we expect
79 * "reasonable" behavior, and run some additional tests relating to event
80 * management on O_RDWR fifo descriptors.
81 */
82
83 #define KQUEUE_MAX_EVENT 8
84
85 /*
86 * All activity occurs within a temporary directory created early in the
87 * test.
88 */
89 static char temp_dir[PATH_MAX];
90
91 static void __unused
atexit_temp_dir(void)92 atexit_temp_dir(void)
93 {
94
95 rmdir(temp_dir);
96 }
97
98 static void
makefifo(const char * fifoname,const char * testname)99 makefifo(const char *fifoname, const char *testname)
100 {
101
102 if (mkfifo(fifoname, 0700) < 0)
103 err(-1, "%s: makefifo: mkfifo: %s", testname, fifoname);
104 }
105
106 static void
cleanfifo2(const char * fifoname,int fd1,int fd2)107 cleanfifo2(const char *fifoname, int fd1, int fd2)
108 {
109
110 if (fd1 != -1)
111 close(fd1);
112 if (fd2 != -1)
113 close(fd2);
114 (void)unlink(fifoname);
115 }
116
117 static void
cleanfifo3(const char * fifoname,int fd1,int fd2,int fd3)118 cleanfifo3(const char *fifoname, int fd1, int fd2, int fd3)
119 {
120
121 if (fd3 != -1)
122 close(fd3);
123 cleanfifo2(fifoname, fd1, fd2);
124 }
125
126 /*
127 * Open two different file descriptors for a fifo: one read, one write. Do
128 * so using non-blocking opens in order to avoid deadlocking the process.
129 */
130 static int
openfifo(const char * fifoname,int * reader_fdp,int * writer_fdp)131 openfifo(const char *fifoname, int *reader_fdp, int *writer_fdp)
132 {
133 int error, fd1, fd2;
134
135 fd1 = open(fifoname, O_RDONLY | O_NONBLOCK);
136 if (fd1 < 0)
137 return (-1);
138 fd2 = open(fifoname, O_WRONLY | O_NONBLOCK);
139 if (fd2 < 0) {
140 error = errno;
141 close(fd1);
142 errno = error;
143 return (-1);
144 }
145 *reader_fdp = fd1;
146 *writer_fdp = fd2;
147
148 return (0);
149 }
150
151 /*
152 * Open one file descriptor for the fifo, supporting both read and write.
153 */
154 static int
openfifo_rw(const char * fifoname,int * fdp)155 openfifo_rw(const char *fifoname, int *fdp)
156 {
157 int fd;
158
159 fd = open(fifoname, O_RDWR);
160 if (fd < 0)
161 return (-1);
162 *fdp = fd;
163
164 return (0);
165 }
166
167 static int
set_nonblocking(int fd,const char * testname)168 set_nonblocking(int fd, const char *testname)
169 {
170 int flags;
171
172 flags = fcntl(fd, F_GETFL);
173 if (flags < 0) {
174 warn("%s: fcntl(fd, F_GETFL)", testname);
175 return(-1);
176 }
177
178 flags |= O_NONBLOCK;
179
180 if (fcntl(fd, F_SETFL, flags) < 0) {
181 warn("%s: fcntl(fd, 0x%x)", testname, flags);
182 return (-1);
183 }
184
185 return (0);
186 }
187
188 static int
set_blocking(int fd,const char * testname)189 set_blocking(int fd, const char *testname)
190 {
191 int flags;
192
193 flags = fcntl(fd, F_GETFL);
194 if (flags < 0) {
195 warn("%s: fcntl(fd, F_GETFL)", testname);
196 return(-1);
197 }
198
199 flags &= ~O_NONBLOCK;
200
201 if (fcntl(fd, F_SETFL, flags) < 0) {
202 warn("%s: fcntl(fd, 0x%x)", testname, flags);
203 return (-1);
204 }
205
206 return (0);
207 }
208
209 /*
210 * Drain a file descriptor (fifo) of any readable data. Note: resets the
211 * blocking state.
212 */
213 static int
drain_fd(int fd,const char * testname)214 drain_fd(int fd, const char *testname)
215 {
216 ssize_t len;
217 u_char ch;
218
219 if (set_nonblocking(fd, testname) < 0)
220 return (-1);
221
222 while ((len = read(fd, &ch, sizeof(ch))) > 0);
223 if (len < 0) {
224 switch (errno) {
225 case EAGAIN:
226 return (0);
227 default:
228 warn("%s: drain_fd: read", testname);
229 return (-1);
230 }
231 }
232 warn("%s: drain_fd: read: returned 0 bytes", testname);
233 return (-1);
234 }
235
236 /*
237 * Simple I/O test: write ten integers, and make sure we get back the same
238 * integers in the same order. This assumes a minimum fifo buffer > 10
239 * bytes in order to not block and deadlock.
240 */
241 static void
test_simpleio(void)242 test_simpleio(void)
243 {
244 int i, reader_fd, writer_fd;
245 u_char buffer[10];
246 ssize_t len;
247
248 makefifo("testfifo", __func__);
249 if (openfifo("testfifo", &reader_fd, &writer_fd)
250 < 0) {
251 warn("test_simpleio: openfifo: testfifo");
252 cleanfifo2("testfifo", -1, -1);
253 exit(-1);
254 }
255
256 for (i = 0; i < 10; i++)
257 buffer[i] = i;
258
259 len = write(writer_fd, (char *)buffer, sizeof(buffer));
260 if (len < 0) {
261 warn("test_simpleio: write");
262 cleanfifo2("testfifo", reader_fd, writer_fd);
263 exit(-1);
264 }
265 if (len != sizeof(buffer)) {
266 warnx("test_simplio: tried %zu but wrote %zd", sizeof(buffer),
267 len);
268 cleanfifo2("testfifo", reader_fd, writer_fd);
269 exit(-1);
270 }
271
272 len = read(reader_fd, (char *)buffer, sizeof(buffer));
273 if (len < 0) {
274 warn("test_simpleio: read");
275 cleanfifo2("testfifo", reader_fd, writer_fd);
276 exit(-1);
277 }
278 if (len != sizeof(buffer)) {
279 warnx("test_simpleio: tried %zu but read %zd", sizeof(buffer),
280 len);
281 cleanfifo2("testfifo", reader_fd, writer_fd);
282 exit(-1);
283 }
284 for (i = 0; i < 10; i++) {
285 if (buffer[i] == i)
286 continue;
287 warnx("test_simpleio: write byte %d as 0x%02x, but read "
288 "0x%02x", i, i, buffer[i]);
289 cleanfifo2("testfifo", reader_fd, writer_fd);
290 exit(-1);
291 }
292
293 cleanfifo2("testfifo", reader_fd, writer_fd);
294 }
295
296 static volatile int alarm_fired;
297 /*
298 * Non-destructive SIGALRM handler.
299 */
300 static void
sigalarm(int signum __unused)301 sigalarm(int signum __unused)
302 {
303
304 alarm_fired = 1;
305 }
306
307 /*
308 * Wrapper function for write, which uses a timer to interrupt any blocking.
309 * Because we can't reliably detect EINTR for blocking I/O, we also track
310 * whether or not our timeout fired.
311 */
312 static int __unused
timed_write(int fd,void * data,size_t len,ssize_t * written_lenp,int timeout,int * timedoutp,const char * testname)313 timed_write(int fd, void *data, size_t len, ssize_t *written_lenp,
314 int timeout, int *timedoutp, const char *testname)
315 {
316 struct sigaction act, oact;
317 ssize_t written_len;
318 int error;
319
320 alarm_fired = 0;
321 bzero(&act, sizeof(oact));
322 act.sa_handler = sigalarm;
323 if (sigaction(SIGALRM, &act, &oact) < 0) {
324 warn("%s: timed_write: sigaction", testname);
325 return (-1);
326 }
327 alarm(timeout);
328 written_len = write(fd, data, len);
329 error = errno;
330 alarm(0);
331 if (sigaction(SIGALRM, &oact, NULL) < 0) {
332 warn("%s: timed_write: sigaction", testname);
333 return (-1);
334 }
335 if (alarm_fired)
336 *timedoutp = 1;
337 else
338 *timedoutp = 0;
339
340 errno = error;
341 if (written_len < 0)
342 return (-1);
343 *written_lenp = written_len;
344 return (0);
345 }
346
347 /*
348 * Wrapper function for read, which uses a timer to interrupt any blocking.
349 * Because we can't reliably detect EINTR for blocking I/O, we also track
350 * whether or not our timeout fired.
351 */
352 static int
timed_read(int fd,void * data,size_t len,ssize_t * read_lenp,int timeout,int * timedoutp,const char * testname)353 timed_read(int fd, void *data, size_t len, ssize_t *read_lenp,
354 int timeout, int *timedoutp, const char *testname)
355 {
356 struct sigaction act, oact;
357 ssize_t read_len;
358 int error;
359
360 alarm_fired = 0;
361 bzero(&act, sizeof(oact));
362 act.sa_handler = sigalarm;
363 if (sigaction(SIGALRM, &act, &oact) < 0) {
364 warn("%s: timed_write: sigaction", testname);
365 return (-1);
366 }
367 alarm(timeout);
368 read_len = read(fd, data, len);
369 error = errno;
370 alarm(0);
371 if (sigaction(SIGALRM, &oact, NULL) < 0) {
372 warn("%s: timed_write: sigaction", testname);
373 return (-1);
374 }
375 if (alarm_fired)
376 *timedoutp = 1;
377 else
378 *timedoutp = 0;
379
380 errno = error;
381 if (read_len < 0)
382 return (-1);
383 *read_lenp = read_len;
384 return (0);
385 }
386
387 /*
388 * This test operates on blocking and non-blocking fifo file descriptors, in
389 * order to determine whether they block at good moments or not. By good we
390 * mean: don't block for non-blocking sockets, and do block for blocking
391 * ones, assuming there isn't I/O buffer to satisfy the request.
392 *
393 * We use a timeout of 5 seconds, concluding that in 5 seconds either all I/O
394 * that can take place will, and that if we reach the end of the timeout,
395 * then blocking has occurred.
396 *
397 * We assume that the buffer size on a fifo is <512K, and as such, that
398 * writing that much data without an active reader will result in blocking.
399 */
400 static void
test_blocking_read_empty(void)401 test_blocking_read_empty(void)
402 {
403 int reader_fd, ret, timedout, writer_fd;
404 ssize_t len;
405 u_char ch;
406
407 makefifo("testfifo", __func__);
408 if (openfifo("testfifo", &reader_fd, &writer_fd)
409 < 0) {
410 warn("test_blocking_read_empty: openfifo: testfifo");
411 cleanfifo2("testfifo", -1, -1);
412 exit(-1);
413 }
414
415 /*
416 * Read one byte from an empty blocking fifo, block as there is no
417 * data.
418 */
419 if (set_blocking(reader_fd, __func__) < 0) {
420 cleanfifo2("testfifo", reader_fd, writer_fd);
421 exit(-1);
422 }
423
424 ret = timed_read(reader_fd, &ch, sizeof(ch), &len, 5, &timedout,
425 __func__);
426 if (ret != -1) {
427 warnx("test_blocking_read_empty: timed_read: returned "
428 "success");
429 cleanfifo2("testfifo", reader_fd, writer_fd);
430 exit(-1);
431 }
432 if (errno != EINTR) {
433 warn("test_blocking_read_empty: timed_read");
434 cleanfifo2("testfifo", reader_fd, writer_fd);
435 exit(-1);
436 }
437
438 /*
439 * Read one byte from an empty non-blocking fifo, return EAGAIN as
440 * there is no data.
441 */
442 if (set_nonblocking(reader_fd, __func__) < 0) {
443 cleanfifo2("testfifo", reader_fd, writer_fd);
444 exit(-1);
445 }
446
447 ret = timed_read(reader_fd, &ch, sizeof(ch), &len, 5, &timedout,
448 __func__);
449 if (ret != -1) {
450 warnx("test_blocking_read_empty: timed_read: returned "
451 "success");
452 cleanfifo2("testfifo", reader_fd, writer_fd);
453 exit(-1);
454 }
455 if (errno != EAGAIN) {
456 warn("test_blocking_read_empty: timed_read");
457 cleanfifo2("testfifo", reader_fd, writer_fd);
458 exit(-1);
459 }
460
461 cleanfifo2("testfifo", reader_fd, writer_fd);
462 }
463
464 /*
465 * Write one byte to an empty fifo, then try to read one byte and make sure
466 * we don't block in either the write or the read. This tests both for
467 * improper blocking in the send and receive code.
468 */
469 static void
test_blocking_one_byte(void)470 test_blocking_one_byte(void)
471 {
472 int reader_fd, ret, timedout, writer_fd;
473 ssize_t len;
474 u_char ch;
475
476 makefifo("testfifo", __func__);
477 if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
478 warn("test_blocking: openfifo: testfifo");
479 cleanfifo2("testfifo", -1, -1);
480 exit(-1);
481 }
482
483 if (set_blocking(writer_fd, __func__) < 0) {
484 cleanfifo2("testfifo", reader_fd, writer_fd);
485 exit(-1);
486 }
487 if (set_blocking(reader_fd, __func__) < 0) {
488 cleanfifo2("testfifo", reader_fd, writer_fd);
489 exit(-1);
490 }
491
492 ch = 0xfe;
493 ret = timed_write(writer_fd, &ch, sizeof(ch), &len, 5, &timedout,
494 __func__);
495 if (ret < 0) {
496 warn("test_blocking_one_byte: timed_write");
497 cleanfifo2("testfifo", reader_fd, writer_fd);
498 exit(-1);
499 }
500 if (len != sizeof(ch)) {
501 warnx("test_blocking_one_byte: timed_write: tried to write "
502 "%zu, wrote %zd", sizeof(ch), len);
503 cleanfifo2("testfifo", reader_fd, writer_fd);
504 exit(-1);
505 }
506
507 ch = 0xab;
508 ret = timed_read(reader_fd, &ch, sizeof(ch), &len, 5, &timedout,
509 __func__);
510 if (ret < 0) {
511 warn("test_blocking_one_byte: timed_read");
512 cleanfifo2("testfifo", reader_fd, writer_fd);
513 exit(-1);
514 }
515 if (len != sizeof(ch)) {
516 warnx("test_blocking_one_byte: timed_read: wanted %zu, "
517 "read %zd", sizeof(ch), len);
518 cleanfifo2("testfifo", reader_fd, writer_fd);
519 exit(-1);
520 }
521 if (ch != 0xfe) {
522 warnx("test_blocking_one_byte: timed_read: expected to read "
523 "0x%02x, read 0x%02x", 0xfe, ch);
524 cleanfifo2("testfifo", reader_fd, writer_fd);
525 exit(-1);
526 }
527
528 cleanfifo2("testfifo", reader_fd, writer_fd);
529 }
530
531 /*
532 * Write one byte to an empty fifo, then try to read one byte and make sure
533 * we don't get back EAGAIN.
534 */
535 static void
test_nonblocking_one_byte(void)536 test_nonblocking_one_byte(void)
537 {
538 int reader_fd, ret, timedout, writer_fd;
539 ssize_t len;
540 u_char ch;
541
542 makefifo("testfifo", __func__);
543 if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
544 warn("test_nonblocking: openfifo: testfifo");
545 cleanfifo2("testfifo", -1, -1);
546 exit(-1);
547 }
548
549 if (set_nonblocking(reader_fd, __func__) < 0) {
550 cleanfifo2("testfifo", reader_fd, writer_fd);
551 exit(-1);
552 }
553
554 ch = 0xfe;
555 ret = timed_write(writer_fd, &ch, sizeof(ch), &len, 5, &timedout,
556 __func__);
557 if (ret < 0) {
558 warn("test_nonblocking_one_byte: timed_write");
559 cleanfifo2("testfifo", reader_fd, writer_fd);
560 exit(-1);
561 }
562 if (len != sizeof(ch)) {
563 warnx("test_nonblocking_one_byte: timed_write: tried to write "
564 "%zu, wrote %zd", sizeof(ch), len);
565 cleanfifo2("testfifo", reader_fd, writer_fd);
566 exit(-1);
567 }
568
569 ch = 0xab;
570 ret = timed_read(reader_fd, &ch, sizeof(ch), &len, 5, &timedout,
571 __func__);
572 if (ret < 0) {
573 warn("test_nonblocking_one_byte: timed_read");
574 cleanfifo2("testfifo", reader_fd, writer_fd);
575 exit(-1);
576 }
577 if (len != sizeof(ch)) {
578 warnx("test_nonblocking_one_byte: timed_read: wanted %zu, read "
579 "%zd", sizeof(ch), len);
580 cleanfifo2("testfifo", reader_fd, writer_fd);
581 exit(-1);
582 }
583 if (ch != 0xfe) {
584 warnx("test_nonblocking_one_byte: timed_read: expected to read "
585 "0x%02x, read 0x%02x", 0xfe, ch);
586 cleanfifo2("testfifo", reader_fd, writer_fd);
587 exit(-1);
588 }
589
590 cleanfifo2("testfifo", reader_fd, writer_fd);
591 }
592
593 /*
594 * First of two test cases involving a 512K buffer: write the buffer into a
595 * blocking file descriptor. We'd like to know it blocks, but the closest we
596 * can get is to see if SIGALRM fired during the I/O resulting in a partial
597 * write.
598 */
599 static void
test_blocking_partial_write(void)600 test_blocking_partial_write(void)
601 {
602 int reader_fd, ret, timedout, writer_fd;
603 u_char *buffer;
604 ssize_t len;
605
606 makefifo("testfifo", __func__);
607 if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
608 warn("test_blocking_partial_write: openfifo: testfifo");
609 cleanfifo2("testfifo", -1, -1);
610 exit(-1);
611 }
612
613 if (set_blocking(writer_fd, __func__) < 0) {
614 cleanfifo2("testfifo", reader_fd, writer_fd);
615 exit(-1);
616 }
617
618 buffer = malloc(512*1024);
619 if (buffer == NULL) {
620 warn("test_blocking_partial_write: malloc");
621 cleanfifo2("testfifo", reader_fd, writer_fd);
622 exit(-1);
623 }
624 bzero(buffer, 512*1024);
625
626 ret = timed_write(writer_fd, buffer, 512*1024, &len, 5, &timedout,
627 __func__);
628 if (ret < 0) {
629 warn("test_blocking_partial_write: timed_write");
630 free(buffer);
631 cleanfifo2("testfifo", reader_fd, writer_fd);
632 exit(-1);
633 }
634
635 if (!timedout) {
636 warnx("test_blocking_partial_write: timed_write: blocking "
637 "socket didn't time out");
638 free(buffer);
639 cleanfifo2("testfifo", reader_fd, writer_fd);
640 exit(-1);
641 }
642
643 free(buffer);
644
645 if (drain_fd(reader_fd, __func__) < 0) {
646 cleanfifo2("testfifo", reader_fd, writer_fd);
647 exit(-1);
648 }
649
650 cleanfifo2("testfifo", reader_fd, writer_fd);
651 }
652
653 /*
654 * Write a 512K buffer to an empty fifo using a non-blocking file descriptor,
655 * and make sure it doesn't block.
656 */
657 static void
test_nonblocking_partial_write(void)658 test_nonblocking_partial_write(void)
659 {
660 int reader_fd, ret, timedout, writer_fd;
661 u_char *buffer;
662 ssize_t len;
663
664 makefifo("testfifo", __func__);
665 if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
666 warn("test_blocking_partial_write: openfifo: testfifo");
667 cleanfifo2("testfifo", -1, -1);
668 exit(-1);
669 }
670
671 if (set_nonblocking(writer_fd, __func__) < 0) {
672 cleanfifo2("testfifo", reader_fd, writer_fd);
673 exit(-1);
674 }
675
676 buffer = malloc(512*1024);
677 if (buffer == NULL) {
678 warn("test_blocking_partial_write: malloc");
679 cleanfifo2("testfifo", reader_fd, writer_fd);
680 exit(-1);
681 }
682 bzero(buffer, 512*1024);
683
684 ret = timed_write(writer_fd, buffer, 512*1024, &len, 5, &timedout,
685 __func__);
686 if (ret < 0) {
687 warn("test_blocking_partial_write: timed_write");
688 free(buffer);
689 cleanfifo2("testfifo", reader_fd, writer_fd);
690 exit(-1);
691 }
692
693 if (timedout) {
694 warnx("test_blocking_partial_write: timed_write: "
695 "non-blocking socket timed out");
696 free(buffer);
697 cleanfifo2("testfifo", reader_fd, writer_fd);
698 exit(-1);
699 }
700
701 if (len == 0 || len >= 512*1024) {
702 warnx("test_blocking_partial_write: timed_write: requested "
703 "%d, sent %zd", 512*1024, len);
704 free(buffer);
705 cleanfifo2("testfifo", reader_fd, writer_fd);
706 exit(-1);
707 }
708
709 free(buffer);
710
711 if (drain_fd(reader_fd, __func__) < 0) {
712 cleanfifo2("testfifo", reader_fd, writer_fd);
713 exit(-1);
714 }
715
716 cleanfifo2("testfifo", reader_fd, writer_fd);
717 }
718
719 /*
720 * test_coalesce_big_read() verifies that data mingles in the fifo across
721 * message boundaries by performing two small writes, then a bigger read
722 * that should return data from both writes.
723 */
724 static void
test_coalesce_big_read(void)725 test_coalesce_big_read(void)
726 {
727 int i, reader_fd, writer_fd;
728 u_char buffer[10];
729 ssize_t len;
730
731 makefifo("testfifo", __func__);
732 if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
733 warn("test_coalesce_big_read: openfifo: testfifo");
734 cleanfifo2("testfifo", -1, -1);
735 exit(-1);
736 }
737
738 /* Write five, write five, read ten. */
739 for (i = 0; i < 10; i++)
740 buffer[i] = i;
741
742 len = write(writer_fd, buffer, 5);
743 if (len < 0) {
744 warn("test_coalesce_big_read: write 5");
745 cleanfifo2("testfifo", reader_fd, writer_fd);
746 exit(-1);
747 }
748 if (len != 5) {
749 warnx("test_coalesce_big_read: write 5 wrote %zd", len);
750 cleanfifo2("testfifo", reader_fd, writer_fd);
751 exit(-1);
752 }
753
754 len = write(writer_fd, buffer + 5, 5);
755 if (len < 0) {
756 warn("test_coalesce_big_read: write 5");
757 cleanfifo2("testfifo", reader_fd, writer_fd);
758 exit(-1);
759 }
760 if (len != 5) {
761 warnx("test_coalesce_big_read: write 5 wrote %zd", len);
762 cleanfifo2("testfifo", reader_fd, writer_fd);
763 exit(-1);
764 }
765
766 len = read(reader_fd, buffer, 10);
767 if (len < 0) {
768 warn("test_coalesce_big_read: read 10");
769 cleanfifo2("testfifo", reader_fd, writer_fd);
770 exit(-1);
771 }
772 if (len != 10) {
773 warnx("test_coalesce_big_read: read 10 read %zd", len);
774 cleanfifo2("testfifo", reader_fd, writer_fd);
775 exit(-1);
776 }
777
778 for (i = 0; i < 10; i++) {
779 if (buffer[i] == i)
780 continue;
781 warnx("test_coalesce_big_read: expected to read 0x%02x, "
782 "read 0x%02x", i, buffer[i]);
783 cleanfifo2("testfifo", reader_fd, writer_fd);
784 exit(-1);
785 }
786
787 cleanfifo2("testfifo", -1, -1);
788 }
789
790 /*
791 * test_coalesce_big_write() verifies that data mingles in the fifo across
792 * message boundaries by performing one big write, then two smaller reads
793 * that should return sequential elements of data from the write.
794 */
795 static void
test_coalesce_big_write(void)796 test_coalesce_big_write(void)
797 {
798 int i, reader_fd, writer_fd;
799 u_char buffer[10];
800 ssize_t len;
801
802 makefifo("testfifo", __func__);
803 if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
804 warn("test_coalesce_big_write: openfifo: testfifo");
805 cleanfifo2("testfifo", -1, -1);
806 exit(-1);
807 }
808
809 /* Write ten, read five, read five. */
810 for (i = 0; i < 10; i++)
811 buffer[i] = i;
812
813 len = write(writer_fd, buffer, 10);
814 if (len < 0) {
815 warn("test_coalesce_big_write: write 10");
816 cleanfifo2("testfifo", reader_fd, writer_fd);
817 exit(-1);
818 }
819 if (len != 10) {
820 warnx("test_coalesce_big_write: write 10 wrote %zd", len);
821 cleanfifo2("testfifo", reader_fd, writer_fd);
822 exit(-1);
823 }
824
825 len = read(reader_fd, buffer, 5);
826 if (len < 0) {
827 warn("test_coalesce_big_write: read 5");
828 cleanfifo2("testfifo", reader_fd, writer_fd);
829 exit(-1);
830 }
831 if (len != 5) {
832 warnx("test_coalesce_big_write: read 5 read %zd", len);
833 cleanfifo2("testfifo", reader_fd, writer_fd);
834 exit(-1);
835 }
836
837 len = read(reader_fd, buffer + 5, 5);
838 if (len < 0) {
839 warn("test_coalesce_big_write: read 5");
840 cleanfifo2("testfifo", reader_fd, writer_fd);
841 exit(-1);
842 }
843 if (len != 5) {
844 warnx("test_coalesce_big_write: read 5 read %zd", len);
845 cleanfifo2("testfifo", reader_fd, writer_fd);
846 exit(-1);
847 }
848
849 for (i = 0; i < 10; i++) {
850 if (buffer[i] == i)
851 continue;
852 warnx("test_coalesce_big_write: expected to read 0x%02x, "
853 "read 0x%02x", i, buffer[i]);
854 cleanfifo2("testfifo", reader_fd, writer_fd);
855 exit(-1);
856 }
857
858 cleanfifo2("testfifo", -1, -1);
859 }
860
861 static int
poll_status(int fd,int * readable,int * writable,int * exception,const char * testname)862 poll_status(int fd, int *readable, int *writable, int *exception,
863 const char *testname)
864 {
865 struct pollfd fds[1];
866
867 fds[0].fd = fd;
868 fds[0].events = POLLIN | POLLOUT | POLLERR;
869 fds[0].revents = 0;
870
871 if (poll(fds, 1, 0) < 0) {
872 warn("%s: poll", testname);
873 return (-1);
874 }
875 *readable = (fds[0].revents & POLLIN) ? 1 : 0;
876 *writable = (fds[0].revents & POLLOUT) ? 1 : 0;
877 *exception = (fds[0].revents & POLLERR) ? 1 : 0;
878 return (0);
879 }
880
881 static int
select_status(int fd,int * readable,int * writable,int * exception,const char * testname)882 select_status(int fd, int *readable, int *writable, int *exception,
883 const char *testname)
884 {
885 struct fd_set readfds, writefds, exceptfds;
886 struct timeval timeout;
887
888 FD_ZERO(&readfds);
889 FD_ZERO(&writefds);
890 FD_ZERO(&exceptfds);
891 FD_SET(fd, &readfds);
892 FD_SET(fd, &writefds);
893 FD_SET(fd, &exceptfds);
894 timeout.tv_sec = 0;
895 timeout.tv_usec = 0;
896 if (select(fd+1, &readfds, &writefds, &exceptfds, &timeout) < 0) {
897 warn("%s: select", testname);
898 return (-1);
899 }
900 *readable = FD_ISSET(fd, &readfds) ? 1 : 0;
901 *writable = FD_ISSET(fd, &writefds) ? 1 : 0;
902 *exception = FD_ISSET(fd, &exceptfds) ? 1 : 0;
903 return (0);
904 }
905
906 /*
907 * Given an existing kqueue, set up read and write event filters for the
908 * passed file descriptor. Typically called once for the read endpoint, and
909 * once for the write endpoint.
910 */
911 static int
kqueue_setup(int kqueue_fd,int fd,const char * testname)912 kqueue_setup(int kqueue_fd, int fd, const char *testname)
913 {
914 struct kevent kevent_changelist[2];
915 struct kevent kevent_eventlist[KQUEUE_MAX_EVENT], *kp;
916 struct timespec timeout;
917 int i, ret;
918
919 timeout.tv_sec = 0;
920 timeout.tv_nsec = 0;
921
922 bzero(&kevent_changelist, sizeof(kevent_changelist));
923 EV_SET(&kevent_changelist[0], fd, EVFILT_READ, EV_ADD, 0, 0, 0);
924 EV_SET(&kevent_changelist[1], fd, EVFILT_WRITE, EV_ADD, 0, 0, 0);
925
926 bzero(&kevent_eventlist, sizeof(kevent_eventlist));
927 ret = kevent(kqueue_fd, kevent_changelist, 2, kevent_eventlist,
928 KQUEUE_MAX_EVENT, &timeout);
929 if (ret < 0) {
930 warn("%s:%s: kevent initial register", testname, __func__);
931 return (-1);
932 }
933
934 /*
935 * Verify that the events registered alright.
936 */
937 for (i = 0; i < ret; i++) {
938 kp = &kevent_eventlist[i];
939 if (kp->flags != EV_ERROR)
940 continue;
941 errno = kp->data;
942 warn("%s:%s: kevent register index %d", testname, __func__,
943 i);
944 return (-1);
945 }
946
947 return (0);
948 }
949
950 static int
kqueue_status(int kqueue_fd,int fd,int * readable,int * writable,int * exception,const char * testname)951 kqueue_status(int kqueue_fd, int fd, int *readable, int *writable,
952 int *exception, const char *testname)
953 {
954 struct kevent kevent_eventlist[KQUEUE_MAX_EVENT], *kp;
955 struct timespec timeout;
956 int i, ret;
957
958 timeout.tv_sec = 0;
959 timeout.tv_nsec = 0;
960
961 ret = kevent(kqueue_fd, NULL, 0, kevent_eventlist, KQUEUE_MAX_EVENT,
962 &timeout);
963 if (ret < 0) {
964 warn("%s: %s: kevent", testname, __func__);
965 return (-1);
966 }
967
968 *readable = *writable = *exception = 0;
969 for (i = 0; i < ret; i++) {
970 kp = &kevent_eventlist[i];
971 if (kp->ident != (u_int)fd)
972 continue;
973 if (kp->filter == EVFILT_READ)
974 *readable = 1;
975 if (kp->filter == EVFILT_WRITE)
976 *writable = 1;
977 }
978
979 return (0);
980 }
981
982 static int
fionread_status(int fd,int * readable,const char * testname)983 fionread_status(int fd, int *readable, const char *testname)
984 {
985 int i;
986
987 if (ioctl(fd, FIONREAD, &i) < 0) {
988 warn("%s: ioctl(FIONREAD)", testname);
989 return (-1);
990 }
991
992 if (i > 0)
993 *readable = 1;
994 else
995 *readable = 0;
996 return (0);
997 }
998
999 #define READABLE 1
1000 #define WRITABLE 1
1001 #define EXCEPTION 1
1002
1003 #define NOT_READABLE 0
1004 #define NOT_WRITABLE 0
1005 #define NOT_EXCEPTION 0
1006
1007 static int
assert_status(int fd,int kqueue_fd,int assert_readable,int assert_writable,int assert_exception,const char * testname,const char * conditionname,const char * fdname)1008 assert_status(int fd, int kqueue_fd, int assert_readable,
1009 int assert_writable, int assert_exception, const char *testname,
1010 const char *conditionname, const char *fdname)
1011 {
1012 int readable, writable, exception;
1013
1014 if (poll_status(fd, &readable, &writable, &exception, testname) < 0)
1015 return (-1);
1016
1017 if (readable != assert_readable || writable != assert_writable ||
1018 exception != assert_exception) {
1019 warnx("%s: %s polls r:%d, w:%d, e:%d on %s", testname,
1020 fdname, readable, writable, exception, conditionname);
1021 return (-1);
1022 }
1023
1024 if (select_status(fd, &readable, &writable, &exception, testname) < 0)
1025 return (-1);
1026
1027 if (readable != assert_readable || writable != assert_writable ||
1028 exception != assert_exception) {
1029 warnx("%s: %s selects r:%d, w:%d, e:%d on %s", testname,
1030 fdname, readable, writable, exception, conditionname);
1031 return (-1);
1032 }
1033
1034 if (kqueue_status(kqueue_fd, fd, &readable, &writable, &exception,
1035 testname) < 0)
1036 return (-1);
1037
1038 if (readable != assert_readable || writable != assert_writable ||
1039 exception != assert_exception) {
1040 warnx("%s: %s kevent r:%d, w:%d, e:%d on %s", testname,
1041 fdname, readable, writable, exception, conditionname);
1042 return (-1);
1043 }
1044
1045 if (fionread_status(fd, &readable, __func__) < 0)
1046 return (-1);
1047
1048 if (readable != assert_readable) {
1049 warnx("%s: %s fionread r:%d on %s", testname, fdname,
1050 readable, conditionname);
1051 return (-1);
1052 }
1053
1054 return (0);
1055 }
1056
1057 /*
1058 * test_events() uses poll(), select(), and kevent() to query the status of
1059 * fifo file descriptors and determine whether they match expected state
1060 * based on earlier semantic tests: specifically, whether or not poll/select/
1061 * kevent will correctly inform on readable/writable state following I/O.
1062 *
1063 * It would be nice to also test status changes as a result of closing of one
1064 * or another fifo endpoint.
1065 */
1066 static void
test_events_outofbox(void)1067 test_events_outofbox(void)
1068 {
1069 int kqueue_fd, reader_fd, writer_fd;
1070
1071 makefifo("testfifo", __func__);
1072 if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
1073 warn("test_events_outofbox: openfifo: testfifo");
1074 cleanfifo2("testfifo", -1, -1);
1075 exit(-1);
1076 }
1077
1078 kqueue_fd = kqueue();
1079 if (kqueue_fd < 0) {
1080 warn("%s: kqueue", __func__);
1081 cleanfifo2("testfifo", reader_fd, writer_fd);
1082 exit(-1);
1083 }
1084
1085 if (kqueue_setup(kqueue_fd, reader_fd, __func__) < 0) {
1086 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
1087 exit(-1);
1088 }
1089
1090 if (kqueue_setup(kqueue_fd, writer_fd, __func__) < 0) {
1091 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
1092 exit(-1);
1093 }
1094
1095 /*
1096 * Make sure that fresh, out-of-the-box fifo file descriptors have
1097 * good initial states. The reader_fd should have no active state,
1098 * since it will not be readable (no data in pipe), writable (it's
1099 * a read-only descriptor), and there's no reason for error yet.
1100 */
1101 if (assert_status(reader_fd, kqueue_fd, NOT_READABLE, NOT_WRITABLE,
1102 NOT_EXCEPTION, __func__, "create", "reader_fd") < 0) {
1103 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
1104 exit(-1);
1105 }
1106
1107 /*
1108 * Make sure that fresh, out-of-the-box fifo file descriptors have
1109 * good initial states. The writer_fd should be ready to write.
1110 */
1111 if (assert_status(writer_fd, kqueue_fd, NOT_READABLE, WRITABLE,
1112 NOT_EXCEPTION, __func__, "create", "writer_fd") < 0) {
1113 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
1114 exit(-1);
1115 }
1116
1117 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
1118 }
1119
1120 static void
test_events_write_read_byte(void)1121 test_events_write_read_byte(void)
1122 {
1123 int kqueue_fd, reader_fd, writer_fd;
1124 ssize_t len;
1125 u_char ch;
1126
1127 makefifo("testfifo", __func__);
1128 if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
1129 warn("test_events_write_read_byte: openfifo: testfifo");
1130 cleanfifo2("testfifo", -1, -1);
1131 exit(-1);
1132 }
1133
1134 kqueue_fd = kqueue();
1135 if (kqueue_fd < 0) {
1136 warn("%s: kqueue", __func__);
1137 cleanfifo2("testfifo", reader_fd, writer_fd);
1138 exit(-1);
1139 }
1140
1141 if (kqueue_setup(kqueue_fd, reader_fd, __func__) < 0) {
1142 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
1143 exit(-1);
1144 }
1145
1146 if (kqueue_setup(kqueue_fd, writer_fd, __func__) < 0) {
1147 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
1148 exit(-1);
1149 }
1150
1151 /*
1152 * Write a byte to the fifo, and make sure that the read end becomes
1153 * readable, and that the write end remains writable (small write).
1154 */
1155 ch = 0x00;
1156 len = write(writer_fd, &ch, sizeof(ch));
1157 if (len < 0) {
1158 warn("%s: write", __func__);
1159 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
1160 exit(-1);
1161 }
1162
1163 if (assert_status(reader_fd, kqueue_fd, READABLE, NOT_WRITABLE,
1164 NOT_EXCEPTION, __func__, "write", "reader_fd") < 0) {
1165 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
1166 exit(-1);
1167 }
1168
1169 /*
1170 * the writer_fd should remain writable.
1171 */
1172 if (assert_status(writer_fd, kqueue_fd, NOT_READABLE, WRITABLE,
1173 NOT_EXCEPTION, __func__, "write", "writer_fd") < 0) {
1174 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
1175 exit(-1);
1176 }
1177
1178 /*
1179 * Read the byte from the reader_fd, and now confirm that the fifo
1180 * becomes unreadable.
1181 */
1182 len = read(reader_fd, &ch, sizeof(ch));
1183 if (len < 0) {
1184 warn("%s: read", __func__);
1185 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
1186 exit(-1);
1187 }
1188
1189 if (assert_status(reader_fd, kqueue_fd, NOT_READABLE, NOT_WRITABLE,
1190 NOT_EXCEPTION, __func__, "write+read", "reader_fd") < 0) {
1191 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
1192 exit(-1);
1193 }
1194
1195 /*
1196 * The writer_fd should remain writable.
1197 */
1198 if (assert_status(writer_fd, kqueue_fd, NOT_READABLE, WRITABLE,
1199 NOT_EXCEPTION, __func__, "write+read", "writer_fd") < 0) {
1200 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
1201 exit(-1);
1202 }
1203
1204 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
1205 }
1206
1207 /*
1208 * Write a 512k buffer to the fifo in non-blocking mode, and make sure that
1209 * the write end becomes un-writable as a result of a partial write that
1210 * fills the fifo buffer.
1211 */
1212 static void
test_events_partial_write(void)1213 test_events_partial_write(void)
1214 {
1215 int kqueue_fd, reader_fd, writer_fd;
1216 u_char *buffer;
1217 ssize_t len;
1218
1219 makefifo("testfifo", __func__);
1220 if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
1221 warn("test_events_partial_write: openfifo: testfifo");
1222 cleanfifo2("testfifo", -1, -1);
1223 exit(-1);
1224 }
1225
1226 kqueue_fd = kqueue();
1227 if (kqueue_fd < 0) {
1228 warn("%s: kqueue", __func__);
1229 cleanfifo2("testfifo", reader_fd, writer_fd);
1230 exit(-1);
1231 }
1232
1233 if (kqueue_setup(kqueue_fd, reader_fd, __func__) < 0) {
1234 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
1235 exit(-1);
1236 }
1237
1238 if (kqueue_setup(kqueue_fd, writer_fd, __func__) < 0) {
1239 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
1240 exit(-1);
1241 }
1242
1243 if (set_nonblocking(writer_fd, "test_events") < 0) {
1244 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
1245 exit(-1);
1246 }
1247
1248 buffer = malloc(512*1024);
1249 if (buffer == NULL) {
1250 warn("test_events_partial_write: malloc");
1251 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
1252 exit(-1);
1253 }
1254 bzero(buffer, 512*1024);
1255
1256 len = write(writer_fd, buffer, 512*1024);
1257 if (len < 0) {
1258 warn("test_events_partial_write: write");
1259 free(buffer);
1260 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
1261 exit(-1);
1262 }
1263
1264 free(buffer);
1265
1266 if (assert_status(writer_fd, kqueue_fd, NOT_READABLE, NOT_WRITABLE,
1267 NOT_EXCEPTION, __func__, "big write", "writer_fd") < 0) {
1268 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
1269 exit(-1);
1270 }
1271
1272 if (drain_fd(reader_fd, "test_events") < 0) {
1273 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
1274 exit(-1);
1275 }
1276
1277 /*
1278 * Test that the writer_fd has been restored to writable state after
1279 * draining.
1280 */
1281 if (assert_status(writer_fd, kqueue_fd, NOT_READABLE, WRITABLE,
1282 NOT_EXCEPTION, __func__, "big write + drain", "writer_fd") < 0) {
1283 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
1284 exit(-1);
1285 }
1286
1287 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
1288 }
1289
1290 /*
1291 * We don't comprehensively test O_RDWR file descriptors, but do run a couple
1292 * of event tests to make sure that the fifo implementation doesn't mixed up
1293 * status checks. In particular, at least one past FreeBSD bug exists in
1294 * which the FIONREAD test was performed on the wrong socket implementing the
1295 * fifo, resulting in the fifo never returning readable.
1296 */
1297 static void
test_events_rdwr(void)1298 test_events_rdwr(void)
1299 {
1300 int fd, kqueue_fd;
1301 ssize_t len;
1302 char ch;
1303
1304 makefifo("testfifo", __func__);
1305 if (openfifo_rw("testfifo", &fd) < 0) {
1306 warn("%s: openfifo_rw: testfifo", __func__);
1307 cleanfifo2("testfifo", -1, -1);
1308 exit(-1);
1309 }
1310
1311 kqueue_fd = kqueue();
1312 if (kqueue_fd < 0) {
1313 warn("%s: kqueue", __func__);
1314 cleanfifo2("testifo", fd, -1);
1315 exit(-1);
1316 }
1317
1318 if (kqueue_setup(kqueue_fd, fd, __func__) < 0) {
1319 cleanfifo2("testfifo", fd, kqueue_fd);
1320 exit(-1);
1321 }
1322
1323 /*
1324 * On first creation, the O_RDWR descriptor should be writable but
1325 * not readable.
1326 */
1327 if (assert_status(fd, kqueue_fd, NOT_READABLE, WRITABLE,
1328 NOT_EXCEPTION, __func__, "create", "fd") < 0) {
1329 cleanfifo2("testfifo", fd, kqueue_fd);
1330 exit(-1);
1331 }
1332
1333 /*
1334 * Write a byte, which should cause the file descriptor to become
1335 * readable and writable.
1336 */
1337 ch = 0x00;
1338 len = write(fd, &ch, sizeof(ch));
1339 if (len < 0) {
1340 warn("%s: write", __func__);
1341 cleanfifo2("testfifo", fd, kqueue_fd);
1342 exit(-1);
1343 }
1344
1345 if (assert_status(fd, kqueue_fd, READABLE, WRITABLE, NOT_EXCEPTION,
1346 __func__, "write", "fd") < 0) {
1347 cleanfifo2("testfifo", fd, kqueue_fd);
1348 exit(-1);
1349 }
1350
1351 /*
1352 * Read a byte, which should cause the file descriptor to return to
1353 * simply being writable.
1354 */
1355 len = read(fd, &ch, sizeof(ch));
1356 if (len < 0) {
1357 warn("%s: read", __func__);
1358 cleanfifo2("testfifo", fd, kqueue_fd);
1359 exit(-1);
1360 }
1361
1362 if (assert_status(fd, kqueue_fd, NOT_READABLE, WRITABLE,
1363 NOT_EXCEPTION, __func__, "write+read", "fd") < 0) {
1364 cleanfifo2("testfifo", fd, kqueue_fd);
1365 exit(-1);
1366 }
1367
1368 cleanfifo2("testfifo", fd, kqueue_fd);
1369 }
1370
1371 int
main(void)1372 main(void)
1373 {
1374
1375 strcpy(temp_dir, "fifo_io.XXXXXXXXXXX");
1376 if (mkdtemp(temp_dir) == NULL)
1377 err(-1, "mkdtemp");
1378 atexit(atexit_temp_dir);
1379
1380 if (chdir(temp_dir) < 0)
1381 err(-1, "chdir %s", temp_dir);
1382
1383 test_simpleio();
1384 test_blocking_read_empty();
1385 test_blocking_one_byte();
1386 test_nonblocking_one_byte();
1387 test_blocking_partial_write();
1388 test_nonblocking_partial_write();
1389 test_coalesce_big_read();
1390 test_coalesce_big_write();
1391 test_events_outofbox();
1392 test_events_write_read_byte();
1393 test_events_partial_write();
1394 test_events_rdwr();
1395
1396 return (0);
1397 }
1398