diff dep/animone/src/fd/xnu.cc @ 258:862d0d8619f6

*: HUUUGE changes animia has been renamed to animone, so instead of thinking of a health condition, you think of a beautiful flower :) I've also edited some of the code for animone, but I have no idea if it even works or not because I don't have a mac or windows machine lying around. whoops! ... anyway, all of the changes divergent from Anisthesia are now licensed under BSD. it's possible that I could even rewrite most of the code to where I don't even have to keep the MIT license, but that's thinking too far into the future I've been slacking off on implementing the anime seasons page, mostly out of laziness. I think I'd have to create another db file specifically for the seasons anyway, this code is being pushed *primarily* because the hard drive it's on is failing! yay :)
author Paper <paper@paper.us.eu.org>
date Mon, 01 Apr 2024 02:43:44 -0400
parents
children 0718f538c5f9
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dep/animone/src/fd/xnu.cc	Mon Apr 01 02:43:44 2024 -0400
@@ -0,0 +1,84 @@
+#include "animone/fd/xnu.h"
+#include "animone.h"
+#include "animone/util/osx.h"
+
+#include <cassert>
+#include <memory>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+#include <fcntl.h>
+#include <libproc.h>
+#include <sys/sysctl.h>
+#include <sys/types.h>
+#include <sys/user.h>
+
+namespace animone::internal::xnu {
+
+bool EnumerateOpenProcesses(process_proc_t process_proc) {
+	size_t pids_size = 256;
+	std::unique_ptr<pid_t[]> pids;
+
+	int returned_size = 0;
+	do {
+		pids.reset(new pid_t[pids_size *= 2]);
+		returned_size = proc_listpids(PROC_ALL_PIDS, 0, pids.get(), pids_size * sizeof(pid_t));
+		if (returned_size == -1)
+			return false;
+	} while ((pids_size * sizeof(size_t)) < returned_size);
+
+	for (int i = 0; i < pids_size; i++) {
+		std::string result;
+		osx::util::GetProcessName(pids[i], result);
+		if (!process_proc({pids[i], result}))
+			return false;
+	}
+
+	return true;
+}
+
+bool EnumerateOpenFiles(const std::set<pid_t>& pids, open_file_proc_t open_file_proc) {
+	if (!open_file_proc)
+		return false;
+
+	for (const auto& pid : pids) {
+		const int bufsz = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0);
+		if (bufsz < 0)
+			return false;
+
+		const size_t info_len = bufsz / sizeof(struct proc_fdinfo);
+		if (info_len < 1)
+			return false;
+
+		std::unique_ptr<struct proc_fdinfo[]> info(new struct proc_fdinfo[info_len]);
+		if (!info)
+			return false;
+
+		proc_pidinfo(pid, PROC_PIDLISTFDS, 0, info.get(), bufsz);
+
+		for (size_t i = 0; i < info_len; i++) {
+			if (info[i].proc_fdtype == PROX_FDTYPE_VNODE) {
+				struct vnode_fdinfowithpath vnodeInfo;
+
+				int sz = proc_pidfdinfo(pid, info[i].proc_fd, PROC_PIDFDVNODEPATHINFO, &vnodeInfo,
+				                        PROC_PIDFDVNODEPATHINFO_SIZE);
+				if (sz != PROC_PIDFDVNODEPATHINFO_SIZE)
+					return false;
+
+				// This doesn't work (for unknown reasons). I assume somethings fucked up with
+				// my assumptions; I don't care enough to look into it tbh
+				//
+				// if (vnodeInfo.pfi.fi_openflags & O_WRONLY || vnodeInfo.pfi.fi_openflags & O_RDWR)
+				//     continue;
+
+				if (!open_file_proc({pid, vnodeInfo.pvip.vip_path}))
+					return false;
+			}
+		}
+	}
+
+	return true;
+}
+
+} // namespace animone::internal::xnu