comparison 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
comparison
equal deleted inserted replaced
165:8937fb7f2d66 166:54c5d80a737e
1 /* This file uses the FreeBSD-specific libprocstat
2 */
3
4 #include "animia/fd/libutil.h"
5 #include "animia/fd.h"
6 #include "animia.h"
7
8 #include <sys/types.h>
9 #include <sys/sysctl.h>
10 #include <sys/user.h>
11 #include <libutil.h>
12
13 #include <memory>
14
15 namespace animia::internal::libutil {
16
17 static bool IsSystemFile(const std::string& file) {
18 return (!file.find("/usr") || !file.find("/lib") || !file.find("/dev") ||
19 !file.find("/proc"));
20 }
21
22 bool LibutilFdTools::EnumerateOpenProcesses(process_proc_t process_proc) {
23 static const int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0};
24 size_t length = 0;
25
26 sysctl((int*)mib, (sizeof(mib) / sizeof(*mib)) - 1, NULL, &length, NULL, 0);
27
28 std::unique_ptr<struct kinfo_proc[]> result;
29 result.reset(new struct kinfo_proc[length]);
30
31 if (!result.get())
32 return false;
33
34 /* actually get our results */
35 if (sysctl((const int*)mib, (sizeof(mib) / sizeof(*mib)) - 1, result.get(), &length, NULL, 0) == ENOMEM) {
36 result.reset();
37 throw std::bad_alloc();
38 }
39
40 if (length < sizeof(struct kinfo_proc))
41 return false;
42
43 for (int i = 0; i < length / sizeof(result[0]); i++)
44 if (!process_proc({result[i].ki_pid, result[i].ki_comm}))
45 return false;
46
47 return true;
48 }
49
50 bool LibutilFdTools::EnumerateOpenFiles(const std::set<pid_t>& pids, open_file_proc_t open_file_proc) {
51 for (const auto& pid : pids) {
52 int cnt;
53 std::unique_ptr<struct kinfo_file[]> files;
54 files.reset(kinfo_getfile(pid, &cnt));
55 if (!files.get())
56 return false;
57
58 for (int i = 0; i < cnt; i++) {
59 const struct kinfo_file& current = files[i];
60 if (current.kf_vnode_type != KF_VTYPE_VREG)
61 continue;
62
63 if (!open_file_proc({pid, current.kf_path}))
64 return false;
65 }
66 }
67
68 return true;
69 }
70
71 }