summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2005-09-13 17:15:05 +0000
committerrwatson <rwatson@FreeBSD.org>2005-09-13 17:15:05 +0000
commit5d506fa38f2ee2021e50394014b41ea3c268c019 (patch)
treeb5bb5708dae21343bff2d72f63a8a1c8a318e791 /tools
parentdc896e1e4b69830c2b4c9813802dd76b4045b651 (diff)
downloadFreeBSD-src-5d506fa38f2ee2021e50394014b41ea3c268c019.zip
FreeBSD-src-5d506fa38f2ee2021e50394014b41ea3c268c019.tar.gz
Restructure fifo_io event-related tests in order to support test cases
relating to O_RDWR file descriptors, which while not defined in POSIX, are in fact used: (1) Revise assumption that we have two file descriptors when testing I/O operations on a fifo. Provide cleanup routines that handle either two or three file descriptors (including a kqueue descriptor). (2) Add an openfifo_rw() routine to supplement openfifo(). (3) kqueue_setup() now configures an existing kqueue to monitor a new file descriptor, rather than allocating a new kqueue to monitor two existing file descriptors. (4) Wrap all direct poll/select/kqueue/FIONREAD interactions in a single function, assert_status(), which takes a file descriptor, kqueue descriptor, assertion of read/writable/exception states, and test description, then tests the assertion. This reduces the bulk of calls in many of the tests, making them shorter, more readable, and easier to determine correct. (5) Add a new test_events_rdwr() function, which performs a basic create/ write/read event test on a O_RDWR fifo file descriptor. This is currently failed by our fifo code in HEAD due to a bug in FIONREAD handling. Fix to be merged shortly.
Diffstat (limited to 'tools')
-rw-r--r--tools/regression/fifo/fifo_io/fifo_io.c802
1 files changed, 322 insertions, 480 deletions
diff --git a/tools/regression/fifo/fifo_io/fifo_io.c b/tools/regression/fifo/fifo_io/fifo_io.c
index 37f3205..7874d89 100644
--- a/tools/regression/fifo/fifo_io/fifo_io.c
+++ b/tools/regression/fifo/fifo_io/fifo_io.c
@@ -76,8 +76,14 @@
* - XXX: blocked reader semantics?
*
* - XXX: event behavior on remote close?
+ *
+ * Although behavior of O_RDWR isn't defined for fifos by POSIX, we expect
+ * "reasonable" behavior, and run some additional tests relating to event
+ * management on O_RDWR fifo descriptors.
*/
+#define KQUEUE_MAX_EVENT 8
+
/*
* All activity occurs within a temporary directory created early in the
* test.
@@ -100,7 +106,7 @@ makefifo(const char *fifoname, const char *testname)
}
static void
-cleanfifo(const char *fifoname, int fd1, int fd2)
+cleanfifo2(const char *fifoname, int fd1, int fd2)
{
if (fd1 != -1)
@@ -111,14 +117,18 @@ cleanfifo(const char *fifoname, int fd1, int fd2)
}
static void
-cleanfifokq(const char *fifoname, int fd1, int fd2, int fd3)
+cleanfifo3(const char *fifoname, int fd1, int fd2, int fd3)
{
if (fd3 != -1)
close(fd3);
- cleanfifo(fifoname, fd1, fd2);
+ cleanfifo2(fifoname, fd1, fd2);
}
+/*
+ * Open two different file descriptors for a fifo: one read, one write. Do
+ * so using non-blocking opens in order to avoid deadlocking the process.
+ */
static int
openfifo(const char *fifoname, const char *testname, int *reader_fdp,
int *writer_fdp)
@@ -141,6 +151,22 @@ openfifo(const char *fifoname, const char *testname, int *reader_fdp,
return (0);
}
+/*
+ * Open one file descriptor for the fifo, supporting both read and write.
+ */
+static int
+openfifo_rw(const char *fifoname, const char *testname, int *fdp)
+{
+ int fd;
+
+ fd = open(fifoname, O_RDWR);
+ if (fd < 0)
+ return (-1);
+ *fdp = fd;
+
+ return (0);
+}
+
static int
set_nonblocking(int fd, const char *testname)
{
@@ -226,7 +252,7 @@ test_simpleio(void)
if (openfifo("testfifo", "test_simpleio", &reader_fd, &writer_fd)
< 0) {
warn("test_simpleio: openfifo: testfifo");
- cleanfifo("testfifo", -1, -1);
+ cleanfifo2("testfifo", -1, -1);
exit(-1);
}
@@ -236,26 +262,26 @@ test_simpleio(void)
len = write(writer_fd, (char *)buffer, sizeof(buffer));
if (len < 0) {
warn("test_simpleio: write");
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
if (len != sizeof(buffer)) {
warnx("test_simplio: tried %d but wrote %d", sizeof(buffer),
len);
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
len = read(reader_fd, (char *)buffer, sizeof(buffer));
if (len < 0) {
warn("test_simpleio: read");
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
if (len != sizeof(buffer)) {
warnx("test_simpleio: tried %d but read %d", sizeof(buffer),
len);
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
for (i = 0; i < 10; i++) {
@@ -263,11 +289,11 @@ test_simpleio(void)
continue;
warnx("test_simpleio: write byte %d as 0x%02x, but read "
"0x%02x", i, i, buffer[i]);
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
}
static int alarm_fired;
@@ -385,7 +411,7 @@ test_blocking_read_empty(void)
if (openfifo("testfifo", __func__, &reader_fd, &writer_fd)
< 0) {
warn("test_blocking_read_empty: openfifo: testfifo");
- cleanfifo("testfifo", -1, -1);
+ cleanfifo2("testfifo", -1, -1);
exit(-1);
}
@@ -394,7 +420,7 @@ test_blocking_read_empty(void)
* data.
*/
if (set_blocking(reader_fd, __func__) < 0) {
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
@@ -403,12 +429,12 @@ test_blocking_read_empty(void)
if (ret != -1) {
warnx("test_blocking_read_empty: timed_read: returned "
"success");
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
if (errno != EINTR) {
warn("test_blocking_read_empty: timed_read");
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
@@ -417,7 +443,7 @@ test_blocking_read_empty(void)
* there is no data.
*/
if (set_nonblocking(reader_fd, __func__) < 0) {
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
@@ -426,16 +452,16 @@ test_blocking_read_empty(void)
if (ret != -1) {
warnx("test_blocking_read_empty: timed_read: returned "
"success");
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
if (errno != EAGAIN) {
warn("test_blocking_read_empty: timed_read");
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
}
/*
@@ -454,16 +480,16 @@ test_blocking_one_byte(void)
if (openfifo("testfifo", __func__, &reader_fd, &writer_fd)
< 0) {
warn("test_blocking: openfifo: testfifo");
- cleanfifo("testfifo", -1, -1);
+ cleanfifo2("testfifo", -1, -1);
exit(-1);
}
if (set_blocking(writer_fd, __func__) < 0) {
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
if (set_blocking(reader_fd, __func__) < 0) {
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
@@ -472,13 +498,13 @@ test_blocking_one_byte(void)
__func__);
if (ret < 0) {
warn("test_blocking_one_byte: timed_write");
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
if (len != sizeof(ch)) {
warnx("test_blocking_one_byte: timed_write: tried to write "
"%d, wrote %d", sizeof(ch), len);
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
@@ -487,23 +513,23 @@ test_blocking_one_byte(void)
__func__);
if (ret < 0) {
warn("test_blocking_one_byte: timed_read");
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
if (len != sizeof(ch)) {
warnx("test_blocking_one_byte: timed_read: wanted %d, "
"read %d", sizeof(ch), len);
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
if (ch != 0xfe) {
warnx("test_blocking_one_byte: timed_read: expected to read "
"0x%02x, read 0x%02x", 0xfe, ch);
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
}
/*
@@ -521,12 +547,12 @@ test_nonblocking_one_byte(void)
if (openfifo("testfifo", __func__, &reader_fd, &writer_fd)
< 0) {
warn("test_nonblocking: openfifo: testfifo");
- cleanfifo("testfifo", -1, -1);
+ cleanfifo2("testfifo", -1, -1);
exit(-1);
}
if (set_nonblocking(reader_fd, __func__) < 0) {
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
@@ -535,13 +561,13 @@ test_nonblocking_one_byte(void)
__func__);
if (ret < 0) {
warn("test_nonblocking_one_byte: timed_write");
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
if (len != sizeof(ch)) {
warnx("test_nonblocking_one_byte: timed_write: tried to write "
"%d, wrote %d", sizeof(ch), len);
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
@@ -550,23 +576,23 @@ test_nonblocking_one_byte(void)
__func__);
if (ret < 0) {
warn("test_nonblocking_one_byte: timed_read");
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
if (len != sizeof(ch)) {
warnx("test_nonblocking_one_byte: timed_read: wanted %d, read "
"%d", sizeof(ch), len);
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
if (ch != 0xfe) {
warnx("test_nonblocking_one_byte: timed_read: expected to read "
"0x%02x, read 0x%02x", 0xfe, ch);
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
}
/*
@@ -586,19 +612,19 @@ test_blocking_partial_write(void)
if (openfifo("testfifo", __func__, &reader_fd, &writer_fd)
< 0) {
warn("test_blocking_partial_write: openfifo: testfifo");
- cleanfifo("testfifo", -1, -1);
+ cleanfifo2("testfifo", -1, -1);
exit(-1);
}
if (set_blocking(writer_fd, __func__) < 0) {
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
buffer = malloc(512*1024);
if (buffer == NULL) {
warn("test_blocking_partial_write: malloc");
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
bzero(buffer, 512*1024);
@@ -608,7 +634,7 @@ test_blocking_partial_write(void)
if (ret < 0) {
warn("test_blocking_partial_write: timed_write");
free(buffer);
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
@@ -616,18 +642,18 @@ test_blocking_partial_write(void)
warnx("test_blocking_partial_write: timed_write: blocking "
"socket didn't time out");
free(buffer);
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
free(buffer);
if (drain_fd(reader_fd, __func__) < 0) {
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
}
/*
@@ -645,19 +671,19 @@ test_nonblocking_partial_write(void)
if (openfifo("testfifo", __func__, &reader_fd, &writer_fd)
< 0) {
warn("test_blocking_partial_write: openfifo: testfifo");
- cleanfifo("testfifo", -1, -1);
+ cleanfifo2("testfifo", -1, -1);
exit(-1);
}
if (set_nonblocking(writer_fd, __func__) < 0) {
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
buffer = malloc(512*1024);
if (buffer == NULL) {
warn("test_blocking_partial_write: malloc");
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
bzero(buffer, 512*1024);
@@ -667,7 +693,7 @@ test_nonblocking_partial_write(void)
if (ret < 0) {
warn("test_blocking_partial_write: timed_write");
free(buffer);
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
@@ -675,7 +701,7 @@ test_nonblocking_partial_write(void)
warnx("test_blocking_partial_write: timed_write: "
"non-blocking socket timed out");
free(buffer);
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
@@ -683,18 +709,18 @@ test_nonblocking_partial_write(void)
warnx("test_blocking_partial_write: timed_write: requested "
"%d, sent %d", 512*1024, len);
free(buffer);
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
free(buffer);
if (drain_fd(reader_fd, __func__) < 0) {
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
}
/*
@@ -713,7 +739,7 @@ test_coalesce_big_read(void)
if (openfifo("testfifo", __func__, &reader_fd, &writer_fd)
< 0) {
warn("test_coalesce_big_read: openfifo: testfifo");
- cleanfifo("testfifo", -1, -1);
+ cleanfifo2("testfifo", -1, -1);
exit(-1);
}
@@ -724,36 +750,36 @@ test_coalesce_big_read(void)
len = write(writer_fd, buffer, 5);
if (len < 0) {
warn("test_coalesce_big_read: write 5");
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
if (len != 5) {
warnx("test_coalesce_big_read: write 5 wrote %d", len);
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
len = write(writer_fd, buffer + 5, 5);
if (len < 0) {
warn("test_coalesce_big_read: write 5");
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
if (len != 5) {
warnx("test_coalesce_big_read: write 5 wrote %d", len);
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
len = read(reader_fd, buffer, 10);
if (len < 0) {
warn("test_coalesce_big_read: read 10");
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
if (len != 10) {
warnx("test_coalesce_big_read: read 10 read %d", len);
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
@@ -762,11 +788,11 @@ test_coalesce_big_read(void)
continue;
warnx("test_coalesce_big_read: expected to read 0x%02x, "
"read 0x%02x", i, buffer[i]);
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
- cleanfifo("testfifo", -1, -1);
+ cleanfifo2("testfifo", -1, -1);
}
/*
@@ -785,7 +811,7 @@ test_coalesce_big_write(void)
if (openfifo("testfifo", __func__, &reader_fd, &writer_fd)
< 0) {
warn("test_coalesce_big_write: openfifo: testfifo");
- cleanfifo("testfifo", -1, -1);
+ cleanfifo2("testfifo", -1, -1);
exit(-1);
}
@@ -796,36 +822,36 @@ test_coalesce_big_write(void)
len = write(writer_fd, buffer, 10);
if (len < 0) {
warn("test_coalesce_big_write: write 10");
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
if (len != 10) {
warnx("test_coalesce_big_write: write 10 wrote %d", len);
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
len = read(reader_fd, buffer, 5);
if (len < 0) {
warn("test_coalesce_big_write: read 5");
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
if (len != 5) {
warnx("test_coalesce_big_write: read 5 read %d", len);
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
len = read(reader_fd, buffer + 5, 5);
if (len < 0) {
warn("test_coalesce_big_write: read 5");
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
if (len != 5) {
warnx("test_coalesce_big_write: read 5 read %d", len);
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
@@ -834,11 +860,11 @@ test_coalesce_big_write(void)
continue;
warnx("test_coalesce_big_write: expected to read 0x%02x, "
"read 0x%02x", i, buffer[i]);
- cleanfifo("testfifo", reader_fd, writer_fd);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
- cleanfifo("testfifo", -1, -1);
+ cleanfifo2("testfifo", -1, -1);
}
static int
@@ -886,58 +912,47 @@ select_status(int fd, int *readable, int *writable, int *exception,
return (0);
}
+/*
+ * Given an existing kqueue, set up read and write event filters for the
+ * passed file descriptor. Typically called once for the read endpoint, and
+ * once for the write endpoint.
+ */
static int
-kqueue_setup(int reader_fd, int writer_fd, int *kqueue_fdp,
- const char *testname)
+kqueue_setup(int kqueue_fd, int fd, const char *testname)
{
- struct kevent kevent_changelist[4], kevent_eventlist[4], *kp;
+ struct kevent kevent_changelist[2];
+ struct kevent kevent_eventlist[KQUEUE_MAX_EVENT], *kp;
struct timespec timeout;
- int i, kqueue_fd, ret;
-
- kqueue_fd = kqueue();
- if (kqueue_fd < 0) {
- warn("%s: kevent_setup: kqueue", testname);
- return (-1);
- }
+ int i, ret;
timeout.tv_sec = 0;
timeout.tv_nsec = 0;
- /*
- * Add events corresponding to read and write on both descriptors.
- */
bzero(&kevent_changelist, sizeof(kevent_changelist));
- EV_SET(&kevent_changelist[0], reader_fd, EVFILT_READ, EV_ADD, 0, 0,
- 0);
- EV_SET(&kevent_changelist[1], reader_fd, EVFILT_WRITE, EV_ADD, 0, 0,
- 0);
- EV_SET(&kevent_changelist[2], writer_fd, EVFILT_READ, EV_ADD, 0, 0,
- 0);
- EV_SET(&kevent_changelist[3], writer_fd, EVFILT_WRITE, EV_ADD, 0, 0,
- 0);
+ EV_SET(&kevent_changelist[0], fd, EVFILT_READ, EV_ADD, 0, 0, 0);
+ EV_SET(&kevent_changelist[1], fd, EVFILT_WRITE, EV_ADD, 0, 0, 0);
bzero(&kevent_eventlist, sizeof(kevent_eventlist));
- ret = kevent(kqueue_fd, kevent_changelist, 4, kevent_eventlist, 4,
- &timeout);
+ ret = kevent(kqueue_fd, kevent_changelist, 2, kevent_eventlist,
+ KQUEUE_MAX_EVENT, &timeout);
if (ret < 0) {
- warn("%s: kevent initial register", __func__);
- cleanfifo("testfifo", reader_fd, writer_fd);
- exit(-1);
+ warn("%s:%s: kevent initial register", testname, __func__);
+ return (-1);
}
/*
- * Verified that the events registered alright.
+ * Verify that the events registered alright.
*/
for (i = 0; i < ret; i++) {
kp = &kevent_eventlist[i];
if (kp->flags != EV_ERROR)
continue;
errno = kp->data;
- err(-1, "%s: kevent register index %d", __func__, i);
+ warn("%s:%s: kevent register index %d", testname, __func__,
+ i);
+ return (-1);
}
- *kqueue_fdp = kqueue_fd;
-
return (0);
}
@@ -945,20 +960,22 @@ static int
kqueue_status(int kqueue_fd, int fd, int *readable, int *writable,
int *exception, const char *testname)
{
- struct kevent kevent_eventlist[4], *kp;
+ struct kevent kevent_eventlist[KQUEUE_MAX_EVENT], *kp;
struct timespec timeout;
- int i;
+ int i, ret;
timeout.tv_sec = 0;
timeout.tv_nsec = 0;
- if (kevent(kqueue_fd, NULL, 0, kevent_eventlist, 4, &timeout) < 0) {
- warn("%s: kqueue_status: kevent", testname);
+ ret = kevent(kqueue_fd, NULL, 0, kevent_eventlist, KQUEUE_MAX_EVENT,
+ &timeout);
+ if (ret < 0) {
+ warn("%s: %s: kevent", testname, __func__);
return (-1);
}
*readable = *writable = *exception = 0;
- for (i = 0; i < 4; i++) {
+ for (i = 0; i < ret; i++) {
kp = &kevent_eventlist[i];
if (kp->ident != (u_int)fd)
continue;
@@ -988,6 +1005,64 @@ fionread_status(int fd, int *readable, const char *testname)
return (0);
}
+#define READABLE 1
+#define WRITABLE 1
+#define EXCEPTION 1
+
+#define NOT_READABLE 0
+#define NOT_WRITABLE 0
+#define NOT_EXCEPTION 0
+
+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)
+{
+ int readable, writable, exception;
+
+ if (poll_status(fd, &readable, &writable, &exception, testname) < 0)
+ return (-1);
+
+ if (readable != assert_readable || writable != assert_writable ||
+ exception != assert_exception) {
+ warnx("%s: %s polls r:%d, w:%d, e:%d on %s", testname,
+ fdname, readable, writable, exception, conditionname);
+ return (-1);
+ }
+
+ if (select_status(fd, &readable, &writable, &exception, testname) < 0)
+ return (-1);
+
+ if (readable != assert_readable || writable != assert_writable ||
+ exception != assert_exception) {
+ warnx("%s: %s selects r:%d, w:%d, e:%d on %s", testname,
+ fdname, readable, writable, exception, conditionname);
+ return (-1);
+ }
+
+ if (kqueue_status(kqueue_fd, fd, &readable, &writable, &exception,
+ testname) < 0)
+ return (-1);
+
+ if (readable != assert_readable || writable != assert_writable ||
+ exception != assert_exception) {
+ warnx("%s: %s kevent r:%d, w:%d, e:%d on %s", testname,
+ fdname, readable, writable, exception, conditionname);
+ return (-1);
+ }
+
+ if (fionread_status(fd, &readable, __func__) < 0)
+ return (-1);
+
+ if (readable != assert_readable) {
+ warnx("%s: %s fionread r:%d on %s", testname, fdname,
+ readable, conditionname);
+ return (-1);
+ }
+
+ return (0);
+}
+
/*
* test_events() uses poll(), select(), and kevent() to query the status of
* fifo file descriptors and determine whether they match expected state
@@ -1000,76 +1075,41 @@ fionread_status(int fd, int *readable, const char *testname)
static void
test_events_outofbox(void)
{
- int readable, writable, exception;
int kqueue_fd, reader_fd, writer_fd;
makefifo("testfifo", __func__);
- if (openfifo("testfifo", __func__, &reader_fd, &writer_fd)
- < 0) {
+ if (openfifo("testfifo", __func__, &reader_fd, &writer_fd) < 0) {
warn("test_events_outofbox: openfifo: testfifo");
- cleanfifo("testfifo", -1, -1);
- exit(-1);
- }
-
- if (kqueue_setup(reader_fd, writer_fd, &kqueue_fd, __func__) < 0) {
- cleanfifo("testfifo", reader_fd, writer_fd);
- exit(-1);
- }
-
- /*
- * Make sure that fresh, out-of-the-box fifo file descriptors have
- * good initial states. The reader_fd should have no active state,
- * since it will not be readable (no data in pipe), writable (it's
- * a read-only descriptor), and there's no reason for error yet.
- */
- if (poll_status(reader_fd, &readable, &writable, &exception,
- __func__) < 0) {
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
+ cleanfifo2("testfifo", -1, -1);
exit(-1);
}
- if (readable || writable || exception) {
- warnx("test_events_outofbox: reader_fd polls r:%d, w:%d, "
- "e:%d on create", readable, writable, exception);
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (select_status(reader_fd, &readable, &writable, &exception,
- __func__) < 0) {
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (readable || writable || exception) {
- warnx("test_events_outofbox: reader_fd selects r:%d, w:%d, "
- "e:%d on create", readable, writable, exception);
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (kqueue_status(kqueue_fd, reader_fd, &readable, &writable,
- &exception, __func__) < 0) {
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
+ kqueue_fd = kqueue();
+ if (kqueue_fd < 0) {
+ warn("%s: kqueue", __func__);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
exit(-1);
}
- if (readable || writable || exception) {
- warnx("test_events_outofbox: reader_fd kevent r:%d, w:%d, "
- "e:%d on create", readable, writable, exception);
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
+ if (kqueue_setup(kqueue_fd, reader_fd, __func__) < 0) {
+ cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
exit(-1);
}
- if (fionread_status(reader_fd, &readable, __func__) < 0) {
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
+ if (kqueue_setup(kqueue_fd, writer_fd, __func__) < 0) {
+ cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
exit(-1);
}
- if (readable) {
- warnx("test_events_outofbox: reader_fd fionread r:%d on "
- "create", readable);
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
+ /*
+ * Make sure that fresh, out-of-the-box fifo file descriptors have
+ * good initial states. The reader_fd should have no active state,
+ * since it will not be readable (no data in pipe), writable (it's
+ * a read-only descriptor), and there's no reason for error yet.
+ */
+ if (assert_status(reader_fd, kqueue_fd, NOT_READABLE, NOT_WRITABLE,
+ NOT_EXCEPTION, __func__, "create", "reader_fd") < 0) {
+ cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
exit(-1);
}
@@ -1077,64 +1117,18 @@ test_events_outofbox(void)
* Make sure that fresh, out-of-the-box fifo file descriptors have
* good initial states. The writer_fd should be ready to write.
*/
- if (poll_status(writer_fd, &readable, &writable, &exception,
- __func__) < 0) {
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (readable || !writable || exception) {
- warnx("test_events_outofbox: writer_fd polls r:%d, w:%d, "
- "e:%d on create", readable, writable, exception);
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (select_status(writer_fd, &readable, &writable, &exception,
- __func__) < 0) {
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (readable || !writable || exception) {
- warnx("test_events_outofbox: writer_fd selects r:%d, w:%d, "
- "e:%d on create", readable, writable, exception);
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (kqueue_status(kqueue_fd, writer_fd, &readable, &writable,
- &exception, __func__) < 0) {
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (readable || !writable || exception) {
- warnx("test_events_outofbox: writer_fd kevent r:%d, w:%d, "
- "e:%d on create", readable, writable, exception);
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
+ if (assert_status(writer_fd, kqueue_fd, NOT_READABLE, WRITABLE,
+ NOT_EXCEPTION, __func__, "create", "writer_fd") < 0) {
+ cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
exit(-1);
}
- if (fionread_status(writer_fd, &readable, __func__) < 0) {
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (readable) {
- warnx("test_events_outofbox: writer_fd fionread r:%d on "
- "create", readable);
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
+ cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
}
static void
test_events_write_read_byte(void)
{
- int readable, writable, exception;
int kqueue_fd, reader_fd, writer_fd;
ssize_t len;
u_char ch;
@@ -1143,12 +1137,24 @@ test_events_write_read_byte(void)
if (openfifo("testfifo", __func__, &reader_fd, &writer_fd)
< 0) {
warn("test_events_write_read_byte: openfifo: testfifo");
- cleanfifo("testfifo", -1, -1);
+ cleanfifo2("testfifo", -1, -1);
+ exit(-1);
+ }
+
+ kqueue_fd = kqueue();
+ if (kqueue_fd < 0) {
+ warn("%s: kqueue", __func__);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
+ exit(-1);
+ }
+
+ if (kqueue_setup(kqueue_fd, reader_fd, __func__) < 0) {
+ cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
exit(-1);
}
- if (kqueue_setup(reader_fd, writer_fd, &kqueue_fd, __func__) < 0) {
- cleanfifo("testfifo", reader_fd, writer_fd);
+ if (kqueue_setup(kqueue_fd, writer_fd, __func__) < 0) {
+ cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
exit(-1);
}
@@ -1159,113 +1165,23 @@ test_events_write_read_byte(void)
ch = 0x00;
len = write(writer_fd, &ch, sizeof(ch));
if (len < 0) {
- warn("test_events_write_read_byte: write");
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
+ warn("%s: write", __func__);
+ cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
exit(-1);
}
- if (poll_status(reader_fd, &readable, &writable, &exception,
- __func__) < 0) {
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (!readable || writable || exception) {
- warnx("test_events_write_read_byte: reader_fd polls r:%d, "
- "w:%d, e:%d after write", readable, writable, exception);
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (select_status(reader_fd, &readable, &writable, &exception,
- __func__) < 0) {
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (!readable || writable || exception) {
- warnx("test_events_write_read_byte: reader_fd selects r:%d, "
- "w:%d, e:%d after write", readable, writable, exception);
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (kqueue_status(kqueue_fd, reader_fd, &readable, &writable,
- &exception, __func__) < 0) {
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (!readable || writable || exception) {
- warnx("test_events_write_read_byte: reader_fd kevent r:%d, "
- "w:%d, e:%d after write", readable, writable, exception);
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (fionread_status(reader_fd, &readable, __func__) < 0) {
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (!readable) {
- warnx("test_events_outofbox: reader_fd fionread r:%d after "
- "write", readable);
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
+ if (assert_status(reader_fd, kqueue_fd, READABLE, NOT_WRITABLE,
+ NOT_EXCEPTION, __func__, "write", "reader_fd") < 0) {
+ cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
exit(-1);
}
/*
- * Now the writer_fd.
+ * the writer_fd should remain writable.
*/
- if (poll_status(writer_fd, &readable, &writable, &exception,
- __func__) < 0) {
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (readable || !writable || exception) {
- warnx("test_events_write_read_byte: writer_fd polls r:%d, "
- "w:%d, e:%d after write", readable, writable, exception);
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (select_status(writer_fd, &readable, &writable, &exception,
- __func__) < 0) {
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (readable || !writable || exception) {
- warnx("test_events_write_read_byte: writer_fd selects r:%d, "
- "w:%d, e:%d after write", readable, writable, exception);
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (kqueue_status(kqueue_fd, writer_fd, &readable, &writable,
- &exception, __func__) < 0) {
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (readable || !writable || exception) {
- warnx("test_events_write_read_byte: writer_fd kevent r:%d, "
- "w:%d, e:%d after write", readable, writable, exception);
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (fionread_status(writer_fd, &readable, __func__) < 0) {
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (readable) {
- warnx("test_events_outofbox: writer_fd fionread r:%d after "
- "write", readable);
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
+ if (assert_status(writer_fd, kqueue_fd, NOT_READABLE, WRITABLE,
+ NOT_EXCEPTION, __func__, "write", "writer_fd") < 0) {
+ cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
exit(-1);
}
@@ -1275,123 +1191,27 @@ test_events_write_read_byte(void)
*/
len = read(reader_fd, &ch, sizeof(ch));
if (len < 0) {
- warn("test_events_write_read_byte: read");
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (poll_status(reader_fd, &readable, &writable, &exception,
- __func__) < 0) {
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (readable || writable || exception) {
- warnx("test_events_write_read_byte: reader_fd polls r:%d, "
- "w:%d, e:%d after write+read", readable, writable,
- exception);
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (select_status(reader_fd, &readable, &writable, &exception,
- __func__) < 0) {
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (readable || writable || exception) {
- warnx("test_events_write_read_byte: reader_fd selects r:%d, "
- "w:%d, e:%d after write+read", readable, writable,
- exception);
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (kqueue_status(kqueue_fd, reader_fd, &readable, &writable,
- &exception, __func__) < 0) {
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (readable || writable || exception) {
- warnx("test_events_write_read_byte: reader_fd kevent r:%d, "
- "w:%d, e:%d after write+read", readable, writable,
- exception);
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (fionread_status(reader_fd, &readable, __func__) < 0) {
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
+ warn("%s: read", __func__);
+ cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
exit(-1);
}
- if (readable) {
- warnx("test_events_outofbox: reader_fd fionread r:%d after "
- "write+read", readable);
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
+ if (assert_status(reader_fd, kqueue_fd, NOT_READABLE, NOT_WRITABLE,
+ NOT_EXCEPTION, __func__, "write+read", "reader_fd") < 0) {
+ cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
exit(-1);
}
/*
- * Now the writer_fd.
+ * The writer_fd should remain writable.
*/
- if (poll_status(writer_fd, &readable, &writable, &exception,
- __func__) < 0) {
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (readable || !writable || exception) {
- warnx("test_events_write_read_byte: writer_fd polls r:%d, "
- "w:%d, e:%d after write+read", readable, writable,
- exception);
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (select_status(writer_fd, &readable, &writable, &exception,
- __func__) < 0) {
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (readable || !writable || exception) {
- warnx("test_events_write_read_byte: writer_fd selects r:%d, "
- "w:%d, e:%d after write+read", readable, writable,
- exception);
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (kqueue_status(kqueue_fd, writer_fd, &readable, &writable,
- &exception, __func__) < 0) {
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (readable || !writable || exception) {
- warnx("test_events_write_read_byte: writer_fd kevent r:%d, "
- "w:%d, e:%d after write+read", readable, writable,
- exception);
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
+ if (assert_status(writer_fd, kqueue_fd, NOT_READABLE, WRITABLE,
+ NOT_EXCEPTION, __func__, "write+read", "writer_fd") < 0) {
+ cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
exit(-1);
}
- if (fionread_status(writer_fd, &readable, __func__) < 0) {
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (readable) {
- warnx("test_events_outofbox: writer_fd fionread r:%d after "
- "write+read", readable);
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
+ cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
}
/*
@@ -1402,7 +1222,6 @@ test_events_write_read_byte(void)
static void
test_events_partial_write(void)
{
- int readable, writable, exception;
int kqueue_fd, reader_fd, writer_fd;
u_char *buffer;
ssize_t len;
@@ -1411,24 +1230,36 @@ test_events_partial_write(void)
if (openfifo("testfifo", __func__, &reader_fd, &writer_fd)
< 0) {
warn("test_events_partial_write: openfifo: testfifo");
- cleanfifo("testfifo", -1, -1);
+ cleanfifo2("testfifo", -1, -1);
+ exit(-1);
+ }
+
+ kqueue_fd = kqueue();
+ if (kqueue_fd < 0) {
+ warn("%s: kqueue", __func__);
+ cleanfifo2("testfifo", reader_fd, writer_fd);
+ exit(-1);
+ }
+
+ if (kqueue_setup(kqueue_fd, reader_fd, __func__) < 0) {
+ cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
exit(-1);
}
- if (kqueue_setup(reader_fd, writer_fd, &kqueue_fd, __func__) < 0) {
- cleanfifo("testfifo", reader_fd, writer_fd);
+ if (kqueue_setup(kqueue_fd, writer_fd, __func__) < 0) {
+ cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
exit(-1);
}
if (set_nonblocking(writer_fd, "test_events") < 0) {
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
+ cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
exit(-1);
}
buffer = malloc(512*1024);
if (buffer == NULL) {
warn("test_events_partial_write: malloc");
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
+ cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
exit(-1);
}
bzero(buffer, 512*1024);
@@ -1437,106 +1268,116 @@ test_events_partial_write(void)
if (len < 0) {
warn("test_events_partial_write: write");
free(buffer);
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
+ cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
exit(-1);
}
free(buffer);
- if (poll_status(writer_fd, &readable, &writable, &exception,
- __func__) < 0) {
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
+ if (assert_status(writer_fd, kqueue_fd, NOT_READABLE, NOT_WRITABLE,
+ NOT_EXCEPTION, __func__, "big write", "writer_fd") < 0) {
+ cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
exit(-1);
}
- if (readable || writable || exception) {
- warnx("test_events_partial_write: writer_fd polls r:%d, "
- "w:%d, e:%d after big write", readable, writable,
- exception);
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
+ if (drain_fd(reader_fd, "test_events") < 0) {
+ cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
exit(-1);
}
- if (select_status(writer_fd, &readable, &writable, &exception,
- __func__) < 0) {
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
+ /*
+ * Test that the writer_fd has been restored to writable state after
+ * draining.
+ */
+ if (assert_status(writer_fd, kqueue_fd, NOT_READABLE, WRITABLE,
+ NOT_EXCEPTION, __func__, "big write + drain", "writer_fd") < 0) {
+ cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
exit(-1);
}
- if (readable || writable || exception) {
- warnx("test_events_partial_write: writer_fd selects r:%d, "
- "w:%d, e:%d after big write", readable, writable,
- exception);
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
+ cleanfifo3("testfifo", reader_fd, writer_fd, kqueue_fd);
+}
- if (kqueue_status(kqueue_fd, writer_fd, &readable, &writable,
- &exception, __func__) < 0) {
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
+/*
+ * We don't comprehensively test O_RDWR file descriptors, but do run a couple
+ * of event tests to make sure that the fifo implementation doesn't mixed up
+ * status checks. In particular, at least one past FreeBSD bug exists in
+ * which the FIONREAD test was performed on the wrong socket implementing the
+ * fifo, resulting in the fifo never returning readable.
+ */
+static void
+test_events_rdwr(void)
+{
+ int fd, kqueue_fd;
+ ssize_t len;
+ char ch;
+
+ makefifo("testfifo", __func__);
+ if (openfifo_rw("testfifo", __func__, &fd)
+ < 0) {
+ warn("%s: openfifo_rw: testfifo", __func__);
+ cleanfifo2("testfifo", -1, -1);
exit(-1);
}
- if (readable || writable || exception) {
- warnx("test_events_partial_write: writer_fd kevent r:%d, "
- "w:%d, e:%d after big write", readable, writable,
- exception);
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
+ kqueue_fd = kqueue();
+ if (kqueue_fd < 0) {
+ warn("%s: kqueue", __func__);
+ cleanfifo2("testifo", fd, -1);
exit(-1);
}
- if (drain_fd(reader_fd, "test_events") < 0) {
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
+ if (kqueue_setup(kqueue_fd, fd, __func__) < 0) {
+ cleanfifo2("testfifo", fd, kqueue_fd);
exit(-1);
}
/*
- * Test that the writer_fd has been restored to writable state after
- * draining.
+ * On first creation, the O_RDWR descriptor should be writable but
+ * not readable.
*/
- if (poll_status(writer_fd, &readable, &writable, &exception,
- __func__) < 0) {
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
- exit(-1);
- }
-
- if (readable || !writable || exception) {
- warnx("test_events_partial_write: writer_fd polls r:%d, "
- "w:%d, e:%d after big write + drain", readable, writable,
- exception);
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
+ if (assert_status(fd, kqueue_fd, NOT_READABLE, WRITABLE,
+ NOT_EXCEPTION, __func__, "create", "fd") < 0) {
+ cleanfifo2("testfifo", fd, kqueue_fd);
exit(-1);
}
- if (select_status(writer_fd, &readable, &writable, &exception,
- __func__) < 0) {
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
+ /*
+ * Write a byte, which should cause the file descriptor to become
+ * readable and writable.
+ */
+ ch = 0x00;
+ len = write(fd, &ch, sizeof(ch));
+ if (len < 0) {
+ warn("%s: write", __func__);
+ cleanfifo2("testfifo", fd, kqueue_fd);
exit(-1);
}
- if (readable || !writable || exception) {
- warnx("test_events_partial_write: writer_fd selects r:%d, "
- "w:%d, e:%d after big write + drain", readable, writable,
- exception);
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
+ if (assert_status(fd, kqueue_fd, READABLE, WRITABLE, NOT_EXCEPTION,
+ __func__, "write", "fd") < 0) {
+ cleanfifo2("testfifo", fd, kqueue_fd);
exit(-1);
}
- if (kqueue_status(kqueue_fd, writer_fd, &readable, &writable,
- &exception, __func__) < 0) {
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
+ /*
+ * Read a byte, which should cause the file descriptor to return to
+ * simply being writable.
+ */
+ len = read(fd, &ch, sizeof(ch));
+ if (len < 0) {
+ warn("%s: read", __func__);
+ cleanfifo2("testfifo", fd, kqueue_fd);
exit(-1);
}
- if (readable || !writable || exception) {
- warnx("test_events_partial_write: writer_fd kevent r:%d, "
- "w:%d, e:%d after big write + drain", readable, writable,
- exception);
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
+ if (assert_status(fd, kqueue_fd, NOT_READABLE, WRITABLE,
+ NOT_EXCEPTION, __func__, "write+read", "fd") < 0) {
+ cleanfifo2("testfifo", fd, kqueue_fd);
exit(-1);
}
- cleanfifokq("testfifo", reader_fd, writer_fd, kqueue_fd);
+ cleanfifo2("testfifo", fd, kqueue_fd);
}
int
@@ -1562,6 +1403,7 @@ main(int argc, char *argv[])
test_events_outofbox();
test_events_write_read_byte();
test_events_partial_write();
+ test_events_rdwr();
return (0);
}
OpenPOWER on IntegriCloud