Mercurial > minori
diff dep/animia/src/fd/libutil.cc @ 166:54c5d80a737e
dep/animia: add libutil method
I changed the "linux" method to be "proc", because it isn't exactly Linux specific
this commit also has some changes to the x11 stuff:
instead of enumerating over only top-level windows, we iterate over ALL of them
this is because many X11 apps actually use multiple windows
for some reason, I still can't get it to work with VLC, but it picks up Firefox...
author | paper@DavesDouble.local |
---|---|
date | Sun, 19 Nov 2023 04:21:56 -0500 |
parents | |
children | bc1ae1810855 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dep/animia/src/fd/libutil.cc Sun Nov 19 04:21:56 2023 -0500 @@ -0,0 +1,71 @@ +/* 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 LibutilFdTools::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 LibutilFdTools::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; +} + +} \ No newline at end of file