2 * Copyright (c) 2005 Robert N. M. Watson
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
29 #include <sys/types.h>
30 #include <sys/event.h>
31 #include <sys/ioctl.h>
32 #include <sys/select.h>
48 * Regression test to exercise POSIX fifo I/O.
50 * We test a number of aspect of behavior, including:
52 * - If there's no data to read, then for blocking fifos, we block, and for
53 * non-blocking, we return EAGAIN.
55 * - If we write ten bytes, ten bytes can be read, and they're the same
56 * bytes, in the same order.
58 * - If we write two batches of five bytes, we can read the same ten bytes in
59 * one read of ten bytes.
61 * - If we write ten bytes, we can read the same ten bytes in two reads of
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.
67 * - That once 512k (ish) is read from the other end, the blocked writer
70 * - When a fifo is empty, poll, select, kqueue, and fionread report it is
71 * writable but not readable.
73 * - When a fifo has data in it, poll, select, and kqueue report that it is
76 * - XXX: blocked reader semantics?
78 * - XXX: event behavior on remote close?
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.
85 #define KQUEUE_MAX_EVENT 8
88 * All activity occurs within a temporary directory created early in the
91 static char temp_dir[PATH_MAX];
101 makefifo(const char *fifoname, const char *testname)
104 if (mkfifo(fifoname, 0700) < 0)
105 err(-1, "%s: makefifo: mkfifo: %s", testname, fifoname);
109 cleanfifo2(const char *fifoname, int fd1, int fd2)
116 (void)unlink(fifoname);
120 cleanfifo3(const char *fifoname, int fd1, int fd2, int fd3)
125 cleanfifo2(fifoname, fd1, fd2);
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.
133 openfifo(const char *fifoname, int *reader_fdp, int *writer_fdp)
137 fd1 = open(fifoname, O_RDONLY | O_NONBLOCK);
140 fd2 = open(fifoname, O_WRONLY | O_NONBLOCK);
154 * Open one file descriptor for the fifo, supporting both read and write.
157 openfifo_rw(const char *fifoname, int *fdp)
161 fd = open(fifoname, O_RDWR);
170 set_nonblocking(int fd, const char *testname)
174 flags = fcntl(fd, F_GETFL);
176 warn("%s: fcntl(fd, F_GETFL)", testname);
182 if (fcntl(fd, F_SETFL, flags) < 0) {
183 warn("%s: fcntl(fd, 0x%x)", testname, flags);
191 set_blocking(int fd, const char *testname)
195 flags = fcntl(fd, F_GETFL);
197 warn("%s: fcntl(fd, F_GETFL)", testname);
201 flags &= ~O_NONBLOCK;
203 if (fcntl(fd, F_SETFL, flags) < 0) {
204 warn("%s: fcntl(fd, 0x%x)", testname, flags);
212 * Drain a file descriptor (fifo) of any readable data. Note: resets the
216 drain_fd(int fd, const char *testname)
221 if (set_nonblocking(fd, testname) < 0)
224 while ((len = read(fd, &ch, sizeof(ch))) > 0);
230 warn("%s: drain_fd: read", testname);
234 warn("%s: drain_fd: read: returned 0 bytes", testname);
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.
246 int i, reader_fd, writer_fd;
250 makefifo("testfifo", __func__);
251 if (openfifo("testfifo", &reader_fd, &writer_fd)
253 warn("test_simpleio: openfifo: testfifo");
254 cleanfifo2("testfifo", -1, -1);
258 for (i = 0; i < 10; i++)
261 len = write(writer_fd, (char *)buffer, sizeof(buffer));
263 warn("test_simpleio: write");
264 cleanfifo2("testfifo", reader_fd, writer_fd);
267 if (len != sizeof(buffer)) {
268 warnx("test_simplio: tried %zu but wrote %zd", sizeof(buffer),
270 cleanfifo2("testfifo", reader_fd, writer_fd);
274 len = read(reader_fd, (char *)buffer, sizeof(buffer));
276 warn("test_simpleio: read");
277 cleanfifo2("testfifo", reader_fd, writer_fd);
280 if (len != sizeof(buffer)) {
281 warnx("test_simpleio: tried %zu but read %zd", sizeof(buffer),
283 cleanfifo2("testfifo", reader_fd, writer_fd);
286 for (i = 0; i < 10; i++) {
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);
295 cleanfifo2("testfifo", reader_fd, writer_fd);
298 static volatile int alarm_fired;
300 * Non-destructive SIGALRM handler.
303 sigalarm(int signum __unused)
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.
315 timed_write(int fd, void *data, size_t len, ssize_t *written_lenp,
316 int timeout, int *timedoutp, const char *testname)
318 struct sigaction act, oact;
323 bzero(&act, sizeof(oact));
324 act.sa_handler = sigalarm;
325 if (sigaction(SIGALRM, &act, &oact) < 0) {
326 warn("%s: timed_write: sigaction", testname);
330 written_len = write(fd, data, len);
333 if (sigaction(SIGALRM, &oact, NULL) < 0) {
334 warn("%s: timed_write: sigaction", testname);
345 *written_lenp = written_len;
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.
355 timed_read(int fd, void *data, size_t len, ssize_t *read_lenp,
356 int timeout, int *timedoutp, const char *testname)
358 struct sigaction act, oact;
363 bzero(&act, sizeof(oact));
364 act.sa_handler = sigalarm;
365 if (sigaction(SIGALRM, &act, &oact) < 0) {
366 warn("%s: timed_write: sigaction", testname);
370 read_len = read(fd, data, len);
373 if (sigaction(SIGALRM, &oact, NULL) < 0) {
374 warn("%s: timed_write: sigaction", testname);
385 *read_lenp = read_len;
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.
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.
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.
403 test_blocking_read_empty(void)
405 int reader_fd, ret, timedout, writer_fd;
409 makefifo("testfifo", __func__);
410 if (openfifo("testfifo", &reader_fd, &writer_fd)
412 warn("test_blocking_read_empty: openfifo: testfifo");
413 cleanfifo2("testfifo", -1, -1);
418 * Read one byte from an empty blocking fifo, block as there is no
421 if (set_blocking(reader_fd, __func__) < 0) {
422 cleanfifo2("testfifo", reader_fd, writer_fd);
426 ret = timed_read(reader_fd, &ch, sizeof(ch), &len, 5, &timedout,
429 warnx("test_blocking_read_empty: timed_read: returned "
431 cleanfifo2("testfifo", reader_fd, writer_fd);
434 if (errno != EINTR) {
435 warn("test_blocking_read_empty: timed_read");
436 cleanfifo2("testfifo", reader_fd, writer_fd);
441 * Read one byte from an empty non-blocking fifo, return EAGAIN as
444 if (set_nonblocking(reader_fd, __func__) < 0) {
445 cleanfifo2("testfifo", reader_fd, writer_fd);
449 ret = timed_read(reader_fd, &ch, sizeof(ch), &len, 5, &timedout,
452 warnx("test_blocking_read_empty: timed_read: returned "
454 cleanfifo2("testfifo", reader_fd, writer_fd);
457 if (errno != EAGAIN) {
458 warn("test_blocking_read_empty: timed_read");
459 cleanfifo2("testfifo", reader_fd, writer_fd);
463 cleanfifo2("testfifo", reader_fd, writer_fd);
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.
472 test_blocking_one_byte(void)
474 int reader_fd, ret, timedout, writer_fd;
478 makefifo("testfifo", __func__);
479 if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
480 warn("test_blocking: openfifo: testfifo");
481 cleanfifo2("testfifo", -1, -1);
485 if (set_blocking(writer_fd, __func__) < 0) {
486 cleanfifo2("testfifo", reader_fd, writer_fd);
489 if (set_blocking(reader_fd, __func__) < 0) {
490 cleanfifo2("testfifo", reader_fd, writer_fd);
495 ret = timed_write(writer_fd, &ch, sizeof(ch), &len, 5, &timedout,
498 warn("test_blocking_one_byte: timed_write");
499 cleanfifo2("testfifo", reader_fd, writer_fd);
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);
510 ret = timed_read(reader_fd, &ch, sizeof(ch), &len, 5, &timedout,
513 warn("test_blocking_one_byte: timed_read");
514 cleanfifo2("testfifo", reader_fd, writer_fd);
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);
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);
530 cleanfifo2("testfifo", reader_fd, writer_fd);
534 * Write one byte to an empty fifo, then try to read one byte and make sure
535 * we don't get back EAGAIN.
538 test_nonblocking_one_byte(void)
540 int reader_fd, ret, timedout, writer_fd;
544 makefifo("testfifo", __func__);
545 if (openfifo("testfifo", &reader_fd, &writer_fd) < 0) {
546 warn("test_nonblocking: openfifo: testfifo");
547 cleanfifo2("testfifo", -1, -1);
551 if (set_nonblocking(reader_fd, __func__) < 0) {
552 cleanfifo2("testfifo", reader_fd, writer_fd);
557 ret = timed_write(writer_fd, &ch, sizeof(ch), &len, 5, &timedout,
560 warn("test_nonblocking_one_byte: timed_write");
561 cleanfifo2("testfifo", reader_fd, writer_fd);
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);
572 ret = timed_read(reader_fd, &ch, sizeof(ch), &len, 5, &timedout,
575 warn("test_nonblocking_one_byte: timed_read");
576 cleanfifo2("testfifo", reader_fd, writer_fd);
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);
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);
592 cleanfifo2("testfifo", reader_fd, writer_fd);
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
602 test_blocking_partial_write(void)
604 int reader_fd, ret, timedout, writer_fd;
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);
615 if (set_blocking(writer_fd, __func__) < 0) {
616 cleanfifo2("testfifo", reader_fd, writer_fd);
620 buffer = malloc(512*1024);
621 if (buffer == NULL) {
622 warn("test_blocking_partial_write: malloc");
623 cleanfifo2("testfifo", reader_fd, writer_fd);
626 bzero(buffer, 512*1024);
628 ret = timed_write(writer_fd, buffer, 512*1024, &len, 5, &timedout,
631 warn("test_blocking_partial_write: timed_write");
633 cleanfifo2("testfifo", reader_fd, writer_fd);
638 warnx("test_blocking_partial_write: timed_write: blocking "
639 "socket didn't time out");
641 cleanfifo2("testfifo", reader_fd, writer_fd);
647 if (drain_fd(reader_fd, __func__) < 0) {
648 cleanfifo2("testfifo", reader_fd, writer_fd);
652 cleanfifo2("testfifo", reader_fd, writer_fd);
656 * Write a 512K buffer to an empty fifo using a non-blocking file descriptor,
657 * and make sure it doesn't block.
660 test_nonblocking_partial_write(void)
662 int reader_fd, ret, timedout, writer_fd;
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);
673 if (set_nonblocking(writer_fd, __func__) < 0) {
674 cleanfifo2("testfifo", reader_fd, writer_fd);
678 buffer = malloc(512*1024);
679 if (buffer == NULL) {
680 warn("test_blocking_partial_write: malloc");
681 cleanfifo2("testfifo", reader_fd, writer_fd);
684 bzero(buffer, 512*1024);
686 ret = timed_write(writer_fd, buffer, 512*1024, &len, 5, &timedout,
689 warn("test_blocking_partial_write: timed_write");
691 cleanfifo2("testfifo", reader_fd, writer_fd);
696 warnx("test_blocking_partial_write: timed_write: "
697 "non-blocking socket timed out");
699 cleanfifo2("testfifo", reader_fd, writer_fd);
703 if (len == 0 || len >= 512*1024) {
704 warnx("test_blocking_partial_write: timed_write: requested "
705 "%d, sent %zd", 512*1024, len);
707 cleanfifo2("testfifo", reader_fd, writer_fd);
713 if (drain_fd(reader_fd, __func__) < 0) {
714 cleanfifo2("testfifo", reader_fd, writer_fd);
718 cleanfifo2("testfifo", reader_fd, writer_fd);
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.
727 test_coalesce_big_read(void)
729 int i, reader_fd, writer_fd;
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);
740 /* Write five, write five, read ten. */
741 for (i = 0; i < 10; i++)
744 len = write(writer_fd, buffer, 5);
746 warn("test_coalesce_big_read: write 5");
747 cleanfifo2("testfifo", reader_fd, writer_fd);
751 warnx("test_coalesce_big_read: write 5 wrote %zd", len);
752 cleanfifo2("testfifo", reader_fd, writer_fd);
756 len = write(writer_fd, buffer + 5, 5);
758 warn("test_coalesce_big_read: write 5");
759 cleanfifo2("testfifo", reader_fd, writer_fd);
763 warnx("test_coalesce_big_read: write 5 wrote %zd", len);
764 cleanfifo2("testfifo", reader_fd, writer_fd);
768 len = read(reader_fd, buffer, 10);
770 warn("test_coalesce_big_read: read 10");
771 cleanfifo2("testfifo", reader_fd, writer_fd);
775 warnx("test_coalesce_big_read: read 10 read %zd", len);
776 cleanfifo2("testfifo", reader_fd, writer_fd);
780 for (i = 0; i < 10; i++) {
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);
789 cleanfifo2("testfifo", -1, -1);
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.
798 test_coalesce_big_write(void)
800 int i, reader_fd, writer_fd;
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);
811 /* Write ten, read five, read five. */
812 for (i = 0; i < 10; i++)
815 len = write(writer_fd, buffer, 10);
817 warn("test_coalesce_big_write: write 10");
818 cleanfifo2("testfifo", reader_fd, writer_fd);
822 warnx("test_coalesce_big_write: write 10 wrote %zd", len);
823 cleanfifo2("testfifo", reader_fd, writer_fd);
827 len = read(reader_fd, buffer, 5);
829 warn("test_coalesce_big_write: read 5");
830 cleanfifo2("testfifo", reader_fd, writer_fd);
834 warnx("test_coalesce_big_write: read 5 read %zd", len);
835 cleanfifo2("testfifo", reader_fd, writer_fd);
839 len = read(reader_fd, buffer + 5, 5);
841 warn("test_coalesce_big_write: read 5");
842 cleanfifo2("testfifo", reader_fd, writer_fd);
846 warnx("test_coalesce_big_write: read 5 read %zd", len);
847 cleanfifo2("testfifo", reader_fd, writer_fd);
851 for (i = 0; i < 10; i++) {
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);
860 cleanfifo2("testfifo", -1, -1);
864 poll_status(int fd, int *readable, int *writable, int *exception,
865 const char *testname)
867 struct pollfd fds[1];
870 fds[0].events = POLLIN | POLLOUT | POLLERR;
873 if (poll(fds, 1, 0) < 0) {
874 warn("%s: poll", testname);
877 *readable = (fds[0].revents & POLLIN) ? 1 : 0;
878 *writable = (fds[0].revents & POLLOUT) ? 1 : 0;
879 *exception = (fds[0].revents & POLLERR) ? 1 : 0;
884 select_status(int fd, int *readable, int *writable, int *exception,
885 const char *testname)
887 struct fd_set readfds, writefds, exceptfds;
888 struct timeval timeout;
893 FD_SET(fd, &readfds);
894 FD_SET(fd, &writefds);
895 FD_SET(fd, &exceptfds);
898 if (select(fd+1, &readfds, &writefds, &exceptfds, &timeout) < 0) {
899 warn("%s: select", testname);
902 *readable = FD_ISSET(fd, &readfds) ? 1 : 0;
903 *writable = FD_ISSET(fd, &writefds) ? 1 : 0;
904 *exception = FD_ISSET(fd, &exceptfds) ? 1 : 0;
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.
914 kqueue_setup(int kqueue_fd, int fd, const char *testname)
916 struct kevent kevent_changelist[2];
917 struct kevent kevent_eventlist[KQUEUE_MAX_EVENT], *kp;
918 struct timespec timeout;
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);
928 bzero(&kevent_eventlist, sizeof(kevent_eventlist));
929 ret = kevent(kqueue_fd, kevent_changelist, 2, kevent_eventlist,
930 KQUEUE_MAX_EVENT, &timeout);
932 warn("%s:%s: kevent initial register", testname, __func__);
937 * Verify that the events registered alright.
939 for (i = 0; i < ret; i++) {
940 kp = &kevent_eventlist[i];
941 if (kp->flags != EV_ERROR)
944 warn("%s:%s: kevent register index %d", testname, __func__,
953 kqueue_status(int kqueue_fd, int fd, int *readable, int *writable,
954 int *exception, const char *testname)
956 struct kevent kevent_eventlist[KQUEUE_MAX_EVENT], *kp;
957 struct timespec timeout;
963 ret = kevent(kqueue_fd, NULL, 0, kevent_eventlist, KQUEUE_MAX_EVENT,
966 warn("%s: %s: kevent", testname, __func__);
970 *readable = *writable = *exception = 0;
971 for (i = 0; i < ret; i++) {
972 kp = &kevent_eventlist[i];
973 if (kp->ident != (u_int)fd)
975 if (kp->filter == EVFILT_READ)
977 if (kp->filter == EVFILT_WRITE)
985 fionread_status(int fd, int *readable, const char *testname)
989 if (ioctl(fd, FIONREAD, &i) < 0) {
990 warn("%s: ioctl(FIONREAD)", testname);
1005 #define NOT_READABLE 0
1006 #define NOT_WRITABLE 0
1007 #define NOT_EXCEPTION 0
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)
1014 int readable, writable, exception;
1016 if (poll_status(fd, &readable, &writable, &exception, testname) < 0)
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);
1026 if (select_status(fd, &readable, &writable, &exception, testname) < 0)
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);
1036 if (kqueue_status(kqueue_fd, fd, &readable, &writable, &exception,
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);
1047 if (fionread_status(fd, &readable, __func__) < 0)
1050 if (readable != assert_readable) {
1051 warnx("%s: %s fionread r:%d on %s", testname, fdname,
1052 readable, conditionname);
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.
1065 * It would be nice to also test status changes as a result of closing of one
1066 * or another fifo endpoint.
1069 test_events_outofbox(void)
1071 int kqueue_fd, reader_fd, writer_fd;
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);
1080 kqueue_fd = kqueue();
1081 if (kqueue_fd < 0) {
1082 warn("%s: kqueue", __func__);
1083 cleanfifo2("testfifo", reader_fd, writer_fd);
1087 if (kqueue_setup(kqueue_fd, reader_fd, __func__) < 0) {
1088 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
1092 if (kqueue_setup(kqueue_fd, writer_fd, __func__) < 0) {
1093 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
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.
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);
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.
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);
1119 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
1123 test_events_write_read_byte(void)
1125 int kqueue_fd, reader_fd, writer_fd;
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);
1136 kqueue_fd = kqueue();
1137 if (kqueue_fd < 0) {
1138 warn("%s: kqueue", __func__);
1139 cleanfifo2("testfifo", reader_fd, writer_fd);
1143 if (kqueue_setup(kqueue_fd, reader_fd, __func__) < 0) {
1144 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
1148 if (kqueue_setup(kqueue_fd, writer_fd, __func__) < 0) {
1149 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
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).
1158 len = write(writer_fd, &ch, sizeof(ch));
1160 warn("%s: write", __func__);
1161 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
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);
1172 * the writer_fd should remain writable.
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);
1181 * Read the byte from the reader_fd, and now confirm that the fifo
1182 * becomes unreadable.
1184 len = read(reader_fd, &ch, sizeof(ch));
1186 warn("%s: read", __func__);
1187 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
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);
1198 * The writer_fd should remain writable.
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);
1206 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
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.
1215 test_events_partial_write(void)
1217 int kqueue_fd, reader_fd, writer_fd;
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);
1228 kqueue_fd = kqueue();
1229 if (kqueue_fd < 0) {
1230 warn("%s: kqueue", __func__);
1231 cleanfifo2("testfifo", reader_fd, writer_fd);
1235 if (kqueue_setup(kqueue_fd, reader_fd, __func__) < 0) {
1236 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
1240 if (kqueue_setup(kqueue_fd, writer_fd, __func__) < 0) {
1241 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
1245 if (set_nonblocking(writer_fd, "test_events") < 0) {
1246 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
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);
1256 bzero(buffer, 512*1024);
1258 len = write(writer_fd, buffer, 512*1024);
1260 warn("test_events_partial_write: write");
1262 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
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);
1274 if (drain_fd(reader_fd, "test_events") < 0) {
1275 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
1280 * Test that the writer_fd has been restored to writable state after
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);
1289 cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
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.
1300 test_events_rdwr(void)
1306 makefifo("testfifo", __func__);
1307 if (openfifo_rw("testfifo", &fd) < 0) {
1308 warn("%s: openfifo_rw: testfifo", __func__);
1309 cleanfifo2("testfifo", -1, -1);
1313 kqueue_fd = kqueue();
1314 if (kqueue_fd < 0) {
1315 warn("%s: kqueue", __func__);
1316 cleanfifo2("testifo", fd, -1);
1320 if (kqueue_setup(kqueue_fd, fd, __func__) < 0) {
1321 cleanfifo2("testfifo", fd, kqueue_fd);
1326 * On first creation, the O_RDWR descriptor should be writable but
1329 if (assert_status(fd, kqueue_fd, NOT_READABLE, WRITABLE,
1330 NOT_EXCEPTION, __func__, "create", "fd") < 0) {
1331 cleanfifo2("testfifo", fd, kqueue_fd);
1336 * Write a byte, which should cause the file descriptor to become
1337 * readable and writable.
1340 len = write(fd, &ch, sizeof(ch));
1342 warn("%s: write", __func__);
1343 cleanfifo2("testfifo", fd, kqueue_fd);
1347 if (assert_status(fd, kqueue_fd, READABLE, WRITABLE, NOT_EXCEPTION,
1348 __func__, "write", "fd") < 0) {
1349 cleanfifo2("testfifo", fd, kqueue_fd);
1354 * Read a byte, which should cause the file descriptor to return to
1355 * simply being writable.
1357 len = read(fd, &ch, sizeof(ch));
1359 warn("%s: read", __func__);
1360 cleanfifo2("testfifo", fd, kqueue_fd);
1364 if (assert_status(fd, kqueue_fd, NOT_READABLE, WRITABLE,
1365 NOT_EXCEPTION, __func__, "write+read", "fd") < 0) {
1366 cleanfifo2("testfifo", fd, kqueue_fd);
1370 cleanfifo2("testfifo", fd, kqueue_fd);
1377 strcpy(temp_dir, "fifo_io.XXXXXXXXXXX");
1378 if (mkdtemp(temp_dir) == NULL)
1380 atexit(atexit_temp_dir);
1382 if (chdir(temp_dir) < 0)
1383 err(-1, "chdir %s", temp_dir);
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();