Mercurial > minori
comparison dep/animia/src/fd/bsd.cc @ 152:8700806c2cc2
dep/animia: awesome new breaking changes!
I'm so tired
author | Paper <mrpapersonic@gmail.com> |
---|---|
date | Wed, 15 Nov 2023 02:34:59 -0500 |
parents | 54744a48a7d7 |
children |
comparison
equal
deleted
inserted
replaced
151:54744a48a7d7 | 152:8700806c2cc2 |
---|---|
1 /** | 1 /* |
2 * fd/bsd.cpp | 2 ** fd/bsd.cpp |
3 * - this ONLY* supports OS X as of now | 3 ** - this ONLY* supports OS X as of now |
4 * (*there is some FreeBSD support code) | 4 ** (*there is some FreeBSD support code) |
5 **/ | 5 */ |
6 #include "animia/fd/bsd.h" | 6 #include "animia/fd/bsd.h" |
7 #include "animia.h" | |
7 | 8 |
8 #include <unordered_map> | 9 #include <unordered_map> |
9 #include <vector> | 10 #include <vector> |
10 #include <iostream> | |
11 #include <string> | 11 #include <string> |
12 | 12 |
13 #include <fcntl.h> | 13 #include <fcntl.h> |
14 #include <sys/sysctl.h> | 14 #include <sys/sysctl.h> |
15 #include <sys/types.h> | 15 #include <sys/types.h> |
21 # include <libproc.h> | 21 # include <libproc.h> |
22 #endif | 22 #endif |
23 | 23 |
24 namespace animia::internal::unix { | 24 namespace animia::internal::unix { |
25 | 25 |
26 /* this is a cleaned up version of a function from... Apple? | 26 static bool GetProcessName(pid_t pid, std::string& result) { |
27 ...anyway, what it essentially does is gets the size and stuff from | |
28 sysctl() and reserves the space in a vector to store the PIDs | |
29 | |
30 TODO: https://kaashif.co.uk/2015/06/18/how-to-get-a-list-of-processes-on-openbsd-in-c/ */ | |
31 bool UnixFdTools::GetAllPids(std::set<pid_t>& pids) { | |
32 struct kinfo_proc* result = NULL; | |
33 size_t length = 0; | |
34 static const int name[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0}; | |
35 | |
36 /* get appropriate length from sysctl() | |
37 note: the reason this isn't checked is actually because this will | |
38 *always* return an error on OS X (or... maybe I'm doing it wrong :) ) */ | |
39 sysctl((int*)name, (sizeof(name) / sizeof(*name)) - 1, NULL, &length, NULL, 0); | |
40 | |
41 result = (struct kinfo_proc*)malloc(length); | |
42 if (result == NULL) | |
43 return std::vector<int>(); | |
44 | |
45 /* TODO: this might actually return ENOMEM if the amount of file handles changes between the | |
46 original sysctl() call and this one, which is technically possible */ | |
47 if (sysctl((int*)name, (sizeof(name) / sizeof(*name)) - 1, result, &length, NULL, 0) == ENOMEM) { | |
48 assert(result != NULL); | |
49 free(result); | |
50 throw std::bad_alloc(); | |
51 } | |
52 | |
53 /* add pids to our vector */ | |
54 pids.reserve(length / sizeof(*result)); | |
55 for (int i = 0; i < length / sizeof(*result); i++) | |
56 pids.insert(result[i].kp_proc.p_pid); | |
57 } | |
58 | |
59 bool UnixFdTools::GetProcessName(pid_t pid, std::string& result) { | |
60 #ifdef __FreeBSD__ | 27 #ifdef __FreeBSD__ |
61 struct kinfo_proc* proc = kinfo_getproc(pid); | 28 struct kinfo_proc* proc = kinfo_getproc(pid); |
62 if (!proc) | 29 if (!proc) |
63 return false; | 30 return false; |
64 result = proc->ki_comm; | 31 result = proc->ki_comm; |
81 result = proc.pbi_name; | 48 result = proc.pbi_name; |
82 return true; | 49 return true; |
83 #endif | 50 #endif |
84 } | 51 } |
85 | 52 |
53 /* this is a cleaned up version of a function from... Apple? | |
54 ...anyway, what it essentially does is gets the size and stuff from | |
55 sysctl() and reserves the space in a vector to store the PIDs | |
56 | |
57 TODO: https://kaashif.co.uk/2015/06/18/how-to-get-a-list-of-processes-on-openbsd-in-c/ */ | |
58 bool UnixFdTools::EnumerateOpenProcesses(process_proc_t process_proc) { | |
59 struct kinfo_proc* result = NULL; | |
60 size_t length = 0; | |
61 static const int name[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0}; | |
62 | |
63 /* get appropriate length from sysctl() | |
64 note: the reason this isn't checked is actually because this will | |
65 *always* return an error on OS X (or... maybe I'm doing it wrong :) ) */ | |
66 sysctl((int*)name, (sizeof(name) / sizeof(*name)) - 1, NULL, &length, NULL, 0); | |
67 | |
68 result = (struct kinfo_proc*)malloc(length); | |
69 if (result == NULL) | |
70 return std::vector<int>(); | |
71 | |
72 /* TODO: this might actually return ENOMEM if the amount of file handles changes between the | |
73 original sysctl() call and this one, which is technically possible */ | |
74 if (sysctl((int*)name, (sizeof(name) / sizeof(*name)) - 1, result, &length, NULL, 0) == ENOMEM) { | |
75 assert(result != NULL); | |
76 free(result); | |
77 throw std::bad_alloc(); | |
78 } | |
79 | |
80 for (int i = 0; i < length / sizeof(*result); i++) { | |
81 const pid_t pid = result[i].kp_proc.p_pid; | |
82 if (!process_proc({pid, GetProcessName(pid)})) | |
83 return false; | |
84 } | |
85 } | |
86 | |
86 /* this only works on OS X :( */ | 87 /* this only works on OS X :( */ |
87 bool UnixFdTools::EnumerateOpenFiles(const std::set<pid_t>& pids, std::vector<std::pair<pid_t, std::string>>& files) { | 88 bool UnixFdTools::EnumerateOpenFiles(const std::set<pid_t>& pids, open_file_proc_t open_file_proc) { |
89 if (!open_file_proc) | |
90 return false; | |
91 | |
88 for (const auto& pid : pids) { | 92 for (const auto& pid : pids) { |
89 int bufsz = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0); | 93 int bufsz = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0); |
90 if (bufsz == -1) | 94 if (bufsz == -1) |
91 return false; | 95 return false; |
92 | 96 |
107 /* this doesn't work! | 111 /* this doesn't work! |
108 if (vnodeInfo.pfi.fi_openflags & O_WRONLY || vnodeInfo.pfi.fi_openflags & O_RDWR) | 112 if (vnodeInfo.pfi.fi_openflags & O_WRONLY || vnodeInfo.pfi.fi_openflags & O_RDWR) |
109 continue; | 113 continue; |
110 */ | 114 */ |
111 | 115 |
112 files.push_back({pid, vnodeInfo.pvip.vip_path}); | 116 if (!open_file_proc({pid, vnodeInfo.pvip.vip_path})) |
117 return false; | |
113 } | 118 } |
114 } | 119 } |
115 } | 120 } |
116 return true; | 121 return true; |
117 } | 122 } |