summaryrefslogtreecommitdiff
path: root/lib/libc_r
diff options
context:
space:
mode:
authorDavid Leonard <d@cvs.openbsd.org>1999-11-30 00:46:20 +0000
committerDavid Leonard <d@cvs.openbsd.org>1999-11-30 00:46:20 +0000
commit1e57f209322e893247e50e0b60c22debf155004e (patch)
treeda8b55c7b20cfefdc41d96132e7249d9fda6340b /lib/libc_r
parentb2a585255ab5d6ec9ce15a7a425da47737ee050e (diff)
test poll()
Diffstat (limited to 'lib/libc_r')
-rw-r--r--lib/libc_r/TEST/test_poll.c135
1 files changed, 135 insertions, 0 deletions
diff --git a/lib/libc_r/TEST/test_poll.c b/lib/libc_r/TEST/test_poll.c
new file mode 100644
index 00000000000..632176ec881
--- /dev/null
+++ b/lib/libc_r/TEST/test_poll.c
@@ -0,0 +1,135 @@
+#include <pthread.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <paths.h>
+#include <unistd.h>
+#include "test.h"
+
+
+#define POLLALL (POLLIN|POLLOUT|POLLERR|POLLNVAL)
+
+static void
+print_pollfd(p)
+ struct pollfd *p;
+{
+
+ printf("{fd=%d, events=< %s%s%s> revents=< %s%s%s%s%s>}",
+ p->fd,
+ p->events & POLLIN ? "in " : "",
+ p->events & POLLOUT ? "out " : "",
+ p->events & ~(POLLIN|POLLOUT) ? "XXX " : "",
+ p->revents & POLLIN ? "in " : "",
+ p->revents & POLLOUT ? "out " : "",
+ p->revents & POLLERR ? "err " : "",
+ p->revents & POLLHUP ? "hup " : "",
+ p->revents & POLLNVAL ? "nval " : ""
+ );
+}
+
+static
+void *
+writer(arg)
+ void *arg;
+{
+ int fd = (int)arg;
+ const char msg[1] = { '!' };
+
+ ASSERTe(write(fd, &msg, sizeof msg), == sizeof msg);
+ return NULL;
+}
+
+static
+void *
+reader(arg)
+ void *arg;
+{
+ int fd = (int)arg;
+ char buf[1];
+
+ ASSERTe(read(fd, &buf, sizeof buf), == sizeof buf);
+ return NULL;
+}
+
+int
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ pthread_t t;
+ void *result;
+ int null, zero, tty;
+ int tube[2];
+ struct pollfd p[3];
+
+ /* Try an empty poll set */
+ ASSERTe(poll(NULL, 0, 0), == 0);
+
+ CHECKe(zero = open(_PATH_DEV "zero", O_RDONLY));
+ CHECKe(null = open(_PATH_DEV "null", O_WRONLY));
+ CHECKe(tty = open(_PATH_DEV "tty", O_WRONLY));
+
+ /* Try both descriptors being ready */
+ p[0].fd = zero;
+ p[0].events = POLLIN|POLLOUT;
+ p[0].revents = 0;
+ p[1].fd = null;
+ p[1].events = POLLIN|POLLOUT;
+ p[1].revents = 0;
+
+ ASSERTe(poll(p, 2, 0), == 2); /* if 4 then bug in kernel not fixed */
+ printf("zero p[0]="); print_pollfd(&p[0]); putchar('\n');
+ printf("null p[1]="); print_pollfd(&p[1]); putchar('\n');
+ ASSERT((p[0].revents & POLLIN) == POLLIN);
+ ASSERT((p[1].revents & POLLOUT) == POLLOUT);
+
+ /*
+ * Try one of the descriptors being invalid
+ * and the other ready
+ */
+ printf("closing zero\n");
+ close(zero);
+
+ p[0].fd = zero;
+ p[0].events = POLLIN|POLLOUT;
+ p[1].fd = null;
+ p[1].events = POLLIN|POLLOUT;
+ ASSERTe(poll(p, 2, 0), == 2); /* again, old kernels had this bug */
+ printf("zero p[0]="); print_pollfd(&p[0]); putchar('\n');
+ printf("null p[1]="); print_pollfd(&p[1]); putchar('\n');
+ ASSERT((p[0].revents & POLLNVAL) == POLLNVAL);
+ ASSERT((p[1].revents & POLLOUT) == POLLOUT);
+
+ printf("closing null\n");
+ close(null);
+
+ /*
+ * New pipes. the write end should be writable (buffered)
+ */
+ CHECKe(pipe(tube));
+ CHECKe(fcntl(tube[0], F_SETFL, O_NONBLOCK));
+ CHECKe(fcntl(tube[1], F_SETFL, O_NONBLOCK));
+
+ p[0].fd = tube[0];
+ p[0].events = POLLIN;
+ p[1].fd = tube[1];
+ p[1].events = POLLOUT;
+ ASSERTe(poll(p, 2, 0), == 1);
+ printf("rpipe p[0]="); print_pollfd(&p[0]); putchar('\n');
+ printf("wpipe p[1]="); print_pollfd(&p[1]); putchar('\n');
+ ASSERT(p[0].revents == 0);
+ ASSERT(p[1].revents == POLLOUT);
+
+ /* Start a writing thread to the write end [1] */
+ printf("bg writing to wpipe\n");
+ CHECKr(pthread_create(&t, NULL, writer, (void *)tube[1]));
+ /* The read end [0] should soon be ready for read (POLLIN) */
+ p[0].fd = tube[0];
+ p[0].events = POLLIN;
+ ASSERTe(poll(p, 1, -1), == 1);
+ printf("rpipe p[0]="); print_pollfd(&p[0]); putchar('\n');
+ ASSERT(p[0].revents == POLLIN);
+ reader((void *)tube[0]); /* consume */
+ CHECKr(pthread_join(t, &result));
+
+ SUCCEED;
+}