Browse Source

poll wrapper around fswait2 (experimental; no POLLOUT, no POLLPRI)

K. Lange 4 years ago
parent
commit
191609c30f
2 changed files with 65 additions and 0 deletions
  1. 19 0
      base/usr/include/poll.h
  2. 46 0
      libc/poll/poll.c

+ 19 - 0
base/usr/include/poll.h

@@ -0,0 +1,19 @@
+#pragma once
+
+#define POLLIN    0x0001
+#define POLLOUT   0x0002
+#define POLLRDHUP 0x0004
+#define POLLERR   0x0008
+#define POLLHUP   0x0010
+#define POLLNVAL  0x0020
+#define POLLPRI   0x0040
+
+typedef unsigned int nfds_t;
+
+struct pollfd {
+	int fd;
+	short events;
+	short revents;
+};
+
+extern int poll(struct pollfd * fds, nfds_t nfds, int timeout);

+ 46 - 0
libc/poll/poll.c

@@ -0,0 +1,46 @@
+#include <poll.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/fswait.h>
+
+extern char * _argv_0;
+
+int poll(struct pollfd *fds, nfds_t nfds, int timeout) {
+	int count_pollin = 0;
+
+	for (nfds_t i = 0; i < nfds; ++i) {
+		if (fds[i].events & POLLIN) {
+			count_pollin++;
+		}
+		fds[i].revents = 0;
+	}
+
+	for (nfds_t i = 0; i < nfds; ++i) {
+		if (fds[i].events & (~POLLIN)) {
+			fprintf(stderr, "%s: poll: unsupported bit set in fds (this implementation only supports POLLIN)\n", _argv_0);
+			return -EINVAL;
+		}
+	}
+
+	int fswait_fds[count_pollin];
+	int fswait_backref[count_pollin];
+	int j = 0;
+	for (nfds_t i = 0; i < nfds; ++i) {
+		if (fds[i].events & POLLIN) {
+			fswait_fds[j] = fds[i].fd;
+			fswait_backref[j] = i;
+			j++;
+		}
+	}
+
+	int ret = fswait2(count_pollin, fswait_fds, timeout);
+
+	if (ret >= 0 && ret < count_pollin) {
+		fds[fswait_backref[ret]].revents = POLLIN;
+		return 1;
+	} else if (ret == count_pollin) {
+		return 0;
+	} else {
+		return ret; /* Error */
+	}
+}