diff --git a/base/usr/include/poll.h b/base/usr/include/poll.h new file mode 100644 index 00000000..c8107396 --- /dev/null +++ b/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); diff --git a/libc/poll/poll.c b/libc/poll/poll.c new file mode 100644 index 00000000..38d16688 --- /dev/null +++ b/libc/poll/poll.c @@ -0,0 +1,46 @@ +#include +#include +#include +#include + +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 */ + } +}