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