Mercurial > minori
view dep/animia/src/fd/libutil.cc @ 233:0a5b6a088886
dep/animia: fix proc readlink
author | Paper <mrpapersonic@gmail.com> |
---|---|
date | Mon, 15 Jan 2024 08:10:58 -0500 |
parents | bc1ae1810855 |
children |
line wrap: on
line source
/* This file uses the FreeBSD-specific libprocstat */ #include "animia/fd/libutil.h" #include "animia/fd.h" #include "animia.h" #include <sys/types.h> #include <sys/sysctl.h> #include <sys/user.h> #include <libutil.h> #include <memory> namespace animia::internal::libutil { static bool IsSystemFile(const std::string& file) { return (!file.find("/usr") || !file.find("/lib") || !file.find("/dev") || !file.find("/proc")); } bool EnumerateOpenProcesses(process_proc_t process_proc) { static const int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0}; size_t length = 0; sysctl((int*)mib, (sizeof(mib) / sizeof(*mib)) - 1, NULL, &length, NULL, 0); std::unique_ptr<struct kinfo_proc[]> result; result.reset(new struct kinfo_proc[length]); if (!result.get()) return false; /* actually get our results */ if (sysctl((const int*)mib, (sizeof(mib) / sizeof(*mib)) - 1, result.get(), &length, NULL, 0) == ENOMEM) { result.reset(); throw std::bad_alloc(); } if (length < sizeof(struct kinfo_proc)) return false; for (int i = 0; i < length / sizeof(result[0]); i++) if (!process_proc({result[i].ki_pid, result[i].ki_comm})) return false; return true; } bool EnumerateOpenFiles(const std::set<pid_t>& pids, open_file_proc_t open_file_proc) { for (const auto& pid : pids) { int cnt; std::unique_ptr<struct kinfo_file[]> files; files.reset(kinfo_getfile(pid, &cnt)); if (!files.get()) return false; for (int i = 0; i < cnt; i++) { const struct kinfo_file& current = files[i]; if (current.kf_vnode_type != KF_VTYPE_VREG) continue; if (!open_file_proc({pid, current.kf_path})) return false; } } return true; } }