From 3d835695e10f540fb786d4ffda44b6e953d4ef1e Mon Sep 17 00:00:00 2001 From: Matthew Rose Date: Wed, 16 Nov 2022 20:35:22 +0100 Subject: 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) --- src/missing.cc | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) 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 /* for syscall and SYS_getdents64 */ #endif +#ifdef __APPLE__ +#include +#include +#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; -- cgit v1.2.1