166
+ − 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 }