aboutsummaryrefslogtreecommitdiffstats
path: root/macpoll.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2023-06-08 16:56:25 -0700
committerKaz Kylheku <kaz@kylheku.com>2023-06-08 16:56:25 -0700
commitf783a3d9b01b1214c3f928deddc86ae5a746ebd4 (patch)
tree5ad35446c17d0fc27798073699cd2ad04fd6751b /macpoll.c
parentdd79082a94b62e0d8c398dcfad19449e72c542da (diff)
downloadpw-f783a3d9b01b1214c3f928deddc86ae5a746ebd4.tar.gz
pw-f783a3d9b01b1214c3f928deddc86ae5a746ebd4.tar.bz2
pw-f783a3d9b01b1214c3f928deddc86ae5a746ebd4.zip
MacOS port.
- The poll function is broken on Darwin (won't handle devices). We make a macpoll out of select and use that. - Makefile adds _D_DARWIN_C_SOURCE to CFLAGS.
Diffstat (limited to 'macpoll.c')
-rw-r--r--macpoll.c83
1 files changed, 83 insertions, 0 deletions
diff --git a/macpoll.c b/macpoll.c
new file mode 100644
index 0000000..82e87ac
--- /dev/null
+++ b/macpoll.c
@@ -0,0 +1,83 @@
+// Pipe Watch ("pw")
+// Copyright 2022-2023 Kaz Kylheku <kaz@kylheku.com>
+//
+// BSD-2 License
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+// POSSIBILITY OF SUCH DAMAGE.
+
+#include <stddef.h>
+#include <sys/select.h>
+#include <poll.h>
+#include <limits.h>
+
+// Would you believe it? MacOS poll() does not support devices, such as TTYs.
+// Here we implement a lame poll using the inefficient select function.
+
+int macpoll(struct pollfd *fds, nfds_t nfds, int timeout)
+{
+ fd_set readfds, writefds, exceptfds;
+ struct timeval tv;
+ int maxfd = 0;
+
+ FD_ZERO(&readfds);
+ FD_ZERO(&writefds);
+ FD_ZERO(&exceptfds);
+
+ for (nfds_t i = 0; i < nfds; i++) {
+ int events = fds[i].events;
+ int fd = fds[i].fd;
+ if (fd < 0)
+ continue;
+ if (fd > maxfd)
+ maxfd = fd;
+ if (events & POLLIN)
+ FD_SET(fd, &readfds);
+ if (events & POLLOUT)
+ FD_SET(fd, &writefds);
+ if (events & POLLERR)
+ FD_SET(fd, &exceptfds);
+ }
+
+ tv.tv_sec = timeout / 1000;
+ tv.tv_usec = (timeout % 1000) * 1000;
+
+ int ret = select(maxfd + 1, &readfds, &writefds, &exceptfds,
+ timeout >= 0 ? &tv : NULL);
+
+ if (ret >= 0) {
+ for (nfds_t i = 0; i < nfds; i++) {
+ int fd = fds[i].fd;
+ int revents = 0;
+ fds[i].revents = 0;
+ if (FD_ISSET(fd, &readfds))
+ revents |= POLLIN;
+ if (FD_ISSET(fd, &writefds))
+ revents |= POLLOUT;
+ if (FD_ISSET(fd, &exceptfds))
+ revents |= POLLERR;
+ fds[i].revents = revents;
+ }
+ }
+
+ return ret;
+}