summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Rose <mattrose@folkwolf.net>2022-11-16 20:35:22 +0100
committerChristian Persch <chpe@src.gnome.org>2022-11-16 20:35:42 +0100
commit3d835695e10f540fb786d4ffda44b6e953d4ef1e (patch)
treef3548fbce21ddd2118b09a2ca395e920eef528d8
parent815d8d323a5c43867c641f2b79aca82788d0b286 (diff)
downloadvte-3d835695e10f540fb786d4ffda44b6e953d4ef1e.tar.gz
missing: Add better fdwalk implementation for darawin
Port of glib!3040 to vte. Fixes: https://gitlab.gnome.org/GNOME/vte/-/issues/2602 (cherry picked from commit 61e705bbd9d92670cca7a8519b62133033791936)
-rw-r--r--src/missing.cc35
1 files changed, 35 insertions, 0 deletions
diff --git a/src/missing.cc b/src/missing.cc
index c0afb6e4..469b3aff 100644
--- a/src/missing.cc
+++ b/src/missing.cc
@@ -28,6 +28,11 @@
#include <sys/syscall.h> /* for syscall and SYS_getdents64 */
#endif
+#ifdef __APPLE__
+#include <libproc.h>
+#include <sys/proc_info.h>
+#endif
+
#include "missing.hh"
/* BEGIN copied from glib
@@ -213,6 +218,36 @@ fdwalk(int (*cb)(void *data, int fd),
return -1;
}
+#if defined(__APPLE__)
+ /* proc_pidinfo isn't documented as async-signal-safe but looking at the implementation
+ * in the darwin tree here:
+ *
+ * https://opensource.apple.com/source/Libc/Libc-498/darwin/libproc.c.auto.html
+ *
+ * It's just a thin wrapper around a syscall, so it's probably okay.
+ */
+ {
+ char buffer[open_max * PROC_PIDLISTFD_SIZE];
+ ssize_t buffer_size;
+
+ buffer_size = proc_pidinfo(getpid(), PROC_PIDLISTFDS, 0, buffer, sizeof(buffer));
+
+ if (buffer_size > 0 &&
+ sizeof(buffer) >= (size_t)buffer_size &&
+ (buffer_size % PROC_PIDLISTFD_SIZE) == 0)
+ {
+ const struct proc_fdinfo *fd_info = (const struct proc_fdinfo *)buffer;
+ size_t number_of_fds = (size_t)buffer_size / PROC_PIDLISTFD_SIZE;
+
+ for (size_t i = 0; i < number_of_fds; i++)
+ if ((res = cb(data, fd_info[i].proc_fd)) != 0)
+ break;
+
+ return res;
+ }
+ }
+#endif
+
for (fd = 0; fd < int(open_max); fd++)
if ((res = cb (data, fd)) != 0)
break;