view dep/animia/src/fd/kvm.cc @ 201:8f6f8dd2eb23

dep/animia: finish kvm backend dep/animia: cmake: don't use kvm on unsupported systems, use private and public includes properly cmake: why are we defining target include directories twice?
author paper@DavesDouble.local
date Sun, 19 Nov 2023 19:13:28 -0500
parents e44b7c428d7c
children 71832ffe425a
line wrap: on
line source

/* kvm.cc: provides support for libkvm in multiple BSDs
**
** this is really the only way to get a thing that works on
** OpenBSD AND NetBSD.
**
** Much of this file is taken from the fstat source code in
** NetBSD.
*/

#include "animia/fd/kvm.h"
#include "animia/fd.h"
#include "animia.h"

#include <sys/types.h>
#include <sys/user.h>
#include <sys/file.h>
#include <sys/filedesc.h>
#include <sys/param.h>
#include <sys/vnode.h>
#include <sys/queue.h>
#include <sys/sysctl.h>

#include <kvm.h>

#include <string>

namespace animia::internal::kvm {

bool KvmFdTools::EnumerateOpenProcesses(process_proc_t process_proc) {
	char errbuf[_POSIX2_LINE_MAX];
	kvm_t* kernel = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf);
	if (!kernel)
		return false;

	int entries = 0;
	struct kinfo_proc* kinfo = kvm_getprocs(kernel, KERN_PROC_ALL, 0, &entries);
	if (!kinfo)
		return false;

	for (int i = 0; i < entries; i++)
		if (!process_proc({kinfo[i].ki_paddr->p_pid, kinfo[i].ki_paddr->p_comm}))
			return false;

	kvm_close(kernel);

	return true;
}

bool KvmFdTools::EnumerateOpenFiles(std::set<pid_t>& pids, open_file_proc_t open_file_proc) {
	char errbuf[_POSIX2_LINE_MAX];
	kvm_t* kernel = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, errbuf);
	if (!kernel)
		return false;

	for (const auto& pid : pids) {
		int cnt;
		struct kinfo_file* kfile = kvm_getfiles(kernel, KERN_FILE_BYPID, pid, &cnt);
		if (!kfile)
			return false;

		for (int i = 0; i < cnt; i++)
			if (!open_file_proc({pid, kfile[i].kf_path}))
				return false;
	}

	kvm_close(kernel);

	return true;
}

}