summaryrefslogtreecommitdiff
path: root/src/util/posix.c
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2023-05-12 20:48:31 +0100
committerEdward Thomson <ethomson@edwardthomson.com>2023-05-13 16:42:04 +0100
commit94f98400bf950aa9835ff9b04c724f2aa3ebd0fc (patch)
tree0dccc76a32683ac34918c8371bcb29f3b489e9bf /src/util/posix.c
parentfad90428970e332153027773b517a1606c0efa1f (diff)
downloadlibgit2-94f98400bf950aa9835ff9b04c724f2aa3ebd0fc.tar.gz
posix: introduce p_poll emulation with select
Not all systems have poll(2); emulate it with select(2).
Diffstat (limited to 'src/util/posix.c')
-rw-r--r--src/util/posix.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/src/util/posix.c b/src/util/posix.c
index b1f85dc94..cfc0e0751 100644
--- a/src/util/posix.c
+++ b/src/util/posix.c
@@ -301,3 +301,57 @@ int p_munmap(git_map *map)
}
#endif
+
+#if defined(GIT_IO_POLL) || defined(GIT_IO_WSAPOLL)
+
+/* Handled by posix.h; this test simplifies the final else */
+
+#elif defined(GIT_IO_SELECT)
+
+int p_poll(struct pollfd *fds, unsigned int nfds, int timeout_ms)
+{
+ fd_set read_fds, write_fds, except_fds;
+ struct timeval timeout = { 0, 0 };
+ unsigned int i;
+ int max_fd = -1, ret;
+
+ FD_ZERO(&read_fds);
+ FD_ZERO(&write_fds);
+ FD_ZERO(&except_fds);
+
+ for (i = 0; i < nfds; i++) {
+ if ((fds[i].events & POLLIN))
+ FD_SET(fds[i].fd, &read_fds);
+
+ if ((fds[i].events & POLLOUT))
+ FD_SET(fds[i].fd, &write_fds);
+
+ if ((fds[i].events & POLLPRI))
+ FD_SET(fds[i].fd, &except_fds);
+
+ max_fd = MAX(max_fd, fds[i].fd);
+ }
+
+ if (timeout_ms > 0) {
+ timeout.tv_sec = timeout_ms / 1000;
+ timeout.tv_usec = (timeout_ms % 1000) * 1000;
+ }
+
+ if ((ret = select(max_fd + 1, &read_fds, &write_fds, &except_fds,
+ timeout_ms < 0 ? NULL : &timeout)) < 0)
+ goto done;
+
+ for (i = 0; i < nfds; i++) {
+ fds[i].revents = 0 |
+ FD_ISSET(fds[i].fd, &read_fds) ? POLLIN : 0 |
+ FD_ISSET(fds[i].fd, &write_fds) ? POLLOUT : 0 |
+ FD_ISSET(fds[i].fd, &except_fds) ? POLLPRI : 0;
+ }
+
+done:
+ return ret;
+}
+
+#else
+# error no poll compatible implementation
+#endif