diff --git a/lib/libc/sys/poll.c b/lib/libc/sys/poll.c new file mode 100644 index 000000000..b5a6937c6 --- /dev/null +++ b/lib/libc/sys/poll.c @@ -0,0 +1,58 @@ +#include +#include +#include +#include +#include +#include + +int poll(struct pollfd *fds, nfds_t nfds, int timeout) { + int kq; + int ret; + struct kevent *events; + struct timespec timeout_ts; + int nevents = 0; + + if (nfds < 0 || nfds > (unsigned int)sysconf(_SC_OPEN_MAX)) { + errno = EINVAL; + return -1; + } + + if (timeout >= 0) { + timeout_ts.tv_sec = timeout / 1000; + timeout_ts.tv_nsec = (timeout % 1000) * 1000000; + } + else if (timeout < -1) { + errno = EINVAL; + return -1; + } + + kq = kqueue(); + if (kq < 0) + return -1; + + events = malloc(nfds * sizeof(struct kevent)); + if (!events) { + errno = ENOMEM; + ret = -1; + goto close_kq; + } + + for (unsigned int i = 0; i < nfds; i++) { + if (fds[i].events | POLLIN) + EV_SET(&events[nevents++], fds[i].fd, EVFILT_READ, EV_ADD, 0, 0, 0); + if (fds[i].events | POLLOUT) + EV_SET(&events[nevents++], fds[i].fd, EVFILT_WRITE, EV_ADD, 0, 0, 0); + } + + ret = kevent(kq, events, nevents, events, nevents, timeout == -1 ? NULL : &timeout_ts); + if (ret == -1) + goto end; + + /* TODO - populate `revents` in elements of `fds` array */ + +end: + free(events); +close_kq: + close(kq); + return ret; +} \ No newline at end of file