summaryrefslogtreecommitdiffstats
path: root/tools/regression
diff options
context:
space:
mode:
Diffstat (limited to 'tools/regression')
-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