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
atexit_temp_dir(void)94 atexit_temp_dir(void)
95 {
96
97 rmdir(temp_dir);
98 }
99
100 static void
makefifo(const char * fifoname,const char * testname)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
cleanfifo2(const char * fifoname,int fd1,int fd2)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
cleanfifo3(const char * fifoname,int fd1,int fd2,int fd3)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
openfifo(const char * fifoname,int * reader_fdp,int * writer_fdp)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
openfifo_rw(const char * fifoname,int * fdp)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
set_nonblocking(int fd,const char * testname)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
set_blocking(int fd,const char * testname)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
drain_fd(int fd,const char * testname)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
test_simpleio(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
sigalarm(int signum __unused)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
timed_write(int fd,void * data,size_t len,ssize_t * written_lenp,int timeout,int * timedoutp,const char * testname)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
timed_read(int fd,void * data,size_t len,ssize_t * read_lenp,int timeout,int * timedoutp,const char * testname)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
test_blocking_read_empty(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
test_blocking_one_byte(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
test_nonblocking_one_byte(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
test_blocking_partial_write(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
test_nonblocking_partial_write(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
test_coalesce_big_read(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
test_coalesce_big_write(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
poll_status(int fd,int * readable,int * writable,int * exception,const char * testname)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
select_status(int fd,int * readable,int * writable,int * exception,const char * testname)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
kqueue_setup(int kqueue_fd,int fd,const char * testname)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
kqueue_status(int kqueue_fd,int fd,int * readable,int * writable,int * exception,const char * testname)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
fionread_status(int fd,int * readable,const char * testname)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
assert_status(int fd,int kqueue_fd,int assert_readable,int assert_writable,int assert_exception,const char * testname,const char * conditionname,const char * fdname)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
test_events_outofbox(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
test_events_write_read_byte(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
test_events_partial_write(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
test_events_rdwr(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
main(void)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