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