diff dep/animia/src/fd/kvm.cc @ 202:71832ffe425a

animia: re-add kvm fd source this is all being merged from my wildly out-of-date laptop. SORRY! in other news, I edited the CI file to install the wayland client as well, so the linux CI build might finally get wayland stuff.
author Paper <paper@paper.us.eu.org>
date Tue, 02 Jan 2024 06:05:06 -0500
parents 8f6f8dd2eb23
children
line wrap: on
line diff
--- a/dep/animia/src/fd/kvm.cc	Sun Nov 19 19:13:28 2023 -0500
+++ b/dep/animia/src/fd/kvm.cc	Tue Jan 02 06:05:06 2024 -0500
@@ -1,10 +1,10 @@
-/* kvm.cc: provides support for libkvm in multiple BSDs
+/* kvm.cc: provides support for OpenBSD's libkvm
 **
-** this is really the only way to get a thing that works on
-** OpenBSD AND NetBSD.
+** Theoretically, this code *should* work, but I haven't
+** even tested it.
 **
-** Much of this file is taken from the fstat source code in
-** NetBSD.
+** This also contains some code to support NetBSD, although
+** it calls the kernel instead of kvm.
 */
 
 #include "animia/fd/kvm.h"
@@ -26,7 +26,7 @@
 
 namespace animia::internal::kvm {
 
-bool KvmFdTools::EnumerateOpenProcesses(process_proc_t process_proc) {
+bool EnumerateOpenProcesses(process_proc_t process_proc) {
 	char errbuf[_POSIX2_LINE_MAX];
 	kvm_t* kernel = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf);
 	if (!kernel)
@@ -46,7 +46,8 @@
 	return true;
 }
 
-bool KvmFdTools::EnumerateOpenFiles(std::set<pid_t>& pids, open_file_proc_t open_file_proc) {
+bool EnumerateOpenFiles(std::set<pid_t>& pids, open_file_proc_t open_file_proc) {
+#ifdef HAVE_KVM_GETFILES
 	char errbuf[_POSIX2_LINE_MAX];
 	kvm_t* kernel = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf);
 	if (!kernel)
@@ -66,6 +67,37 @@
 	kvm_close(kernel);
 
 	return true;
+#else /* For NetBSD... I think */
+	for (const auto& pid : pids) {
+		int mib[6] = {
+			CTL_KERN,
+			KERN_FILE2,
+			KERN_FILE_BYPID,
+			pid,
+			sizeof(struct kinfo_file),
+			0
+		};
+
+		size_t len = 0;
+		if (sysctl(mib, sizeof(mib)/sizeof(mib[0]), NULL, &len, NULL, 0) == -1)
+			return false;
+
+		mib[5] = len / sizeof(struct kinfo_file);
+
+		std::unique_ptr<struct kinfo_file[]> buf(new struct kinfo_file[mib[5]]);
+		if (!buf)
+			return false;
+
+		if (sysctl(mib, sizeof(mib)/sizeof(mib[0]), buf.get(), &len, NULL, 0) == -1)
+			return false;
+
+		for (size_t i = 0; i < cnt; i++)
+			if (!open_file_proc({pid, kfile[i].kf_path}))
+				return false;
+	}
+
+	return true;
+#endif
 }
 
 }