]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - tools/regression/fifo/fifo_io/fifo_io.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / tools / regression / fifo / fifo_io / fifo_io.c
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 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, 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  */
157 static int
158 openfifo_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
170 static int
171 set_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
191 static int
192 set_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  */
216 static int
217 drain_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  */
244 static void
245 test_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
299 static int alarm_fired;
300 /*
301  * Non-destructive SIGALRM handler.
302  */
303 static void
304 sigalarm(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  */
315 static int __unused
316 timed_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  */
355 static int
356 timed_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  */
403 static void
404 test_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  */
472 static void
473 test_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  */
539 static void
540 test_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  */
604 static void
605 test_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  */
663 static void
664 test_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  */
731 static void
732 test_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  */
803 static void
804 test_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
870 static int
871 poll_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
890 static int
891 select_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  */
920 static int
921 kqueue_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
959 static int
960 kqueue_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
991 static int
992 fionread_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
1016 static int
1017 assert_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  */
1075 static void
1076 test_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
1129 static void
1130 test_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  */
1222 static void
1223 test_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  */
1308 static void
1309 test_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
1383 int
1384 main(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 }