Mercurial > minori
comparison dep/animia/src/fd/xnu.cc @ 156:cdf79282d647
dep/animia: add VERY early x11 window stuff
author | Paper <mrpapersonic@gmail.com> |
---|---|
date | Wed, 15 Nov 2023 18:04:04 -0500 |
parents | d2bbb5773616 |
children | 18c8eb5d1edc |
comparison
equal
deleted
inserted
replaced
155:d2bbb5773616 | 156:cdf79282d647 |
---|---|
3 ** - provides support for XNU (part of Darwin) | 3 ** - provides support for XNU (part of Darwin) |
4 */ | 4 */ |
5 #include "animia/fd/xnu.h" | 5 #include "animia/fd/xnu.h" |
6 #include "animia.h" | 6 #include "animia.h" |
7 | 7 |
8 #include <cassert> | |
9 #include <string> | |
8 #include <unordered_map> | 10 #include <unordered_map> |
9 #include <vector> | 11 #include <vector> |
10 #include <string> | |
11 #include <cassert> | |
12 | 12 |
13 #include <fcntl.h> | 13 #include <fcntl.h> |
14 #include <libproc.h> | |
14 #include <sys/sysctl.h> | 15 #include <sys/sysctl.h> |
15 #include <sys/types.h> | 16 #include <sys/types.h> |
16 #include <sys/user.h> | 17 #include <sys/user.h> |
17 #include <libproc.h> | |
18 | 18 |
19 namespace animia::internal::xnu { | 19 namespace animia::internal::xnu { |
20 | 20 |
21 static std::string GetProcessName(pid_t pid) { | 21 static std::string GetProcessName(pid_t pid) { |
22 struct proc_bsdinfo proc; | 22 struct proc_bsdinfo proc; |
23 | 23 |
24 int st = proc_pidinfo(pid, PROC_PIDTBSDINFO, 0, &proc, PROC_PIDTBSDINFO_SIZE); | 24 int st = proc_pidinfo(pid, PROC_PIDTBSDINFO, 0, &proc, PROC_PIDTBSDINFO_SIZE); |
25 if (st != PROC_PIDTBSDINFO_SIZE) | 25 if (st != PROC_PIDTBSDINFO_SIZE) |
26 return ""; | 26 return ""; |
27 | 27 |
28 return proc.pbi_name; | 28 return (proc.pbi_name[0]) ? proc.pbi_name : proc.pbi_comm; |
29 } | 29 } |
30 | 30 |
31 /* this is a cleaned up version of a function from... Apple? | |
32 ...anyway, what it essentially does is gets the size and stuff from | |
33 sysctl() and reserves the space in a vector to store the PIDs */ | |
34 bool XnuFdTools::EnumerateOpenProcesses(process_proc_t process_proc) { | 31 bool XnuFdTools::EnumerateOpenProcesses(process_proc_t process_proc) { |
35 struct kinfo_proc* result = NULL; | 32 std::vector<pid_t> pids; |
36 size_t length = 0; | 33 pids.reserve(1024); |
37 static const int name[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0}; | |
38 | 34 |
39 /* get appropriate length from sysctl() | 35 for (int returned_size = pids.capacity(); pids.capacity() > returned_size; pids.reserve(pids.capacity() * 2)) { |
40 note: the reason this isn't checked is actually because this will | 36 returned_size = proc_listpids(PROC_ALL_PIDS, 0, pids.data(), pids.capacity() * sizeof(pid_t)); |
41 *always* return an error on OS X (or... maybe I'm doing it wrong :) ) */ | 37 if (returned_size == -1) |
42 sysctl((int*)name, (sizeof(name) / sizeof(*name)) - 1, NULL, &length, NULL, 0); | 38 return false; |
43 | |
44 result = (struct kinfo_proc*)malloc(length); | |
45 if (result == NULL) | |
46 return false; | |
47 | |
48 /* TODO: this might actually return ENOMEM if the amount of file handles changes between the | |
49 original sysctl() call and this one, which is technically possible */ | |
50 if (sysctl((int*)name, (sizeof(name) / sizeof(*name)) - 1, result, &length, NULL, 0) == ENOMEM) { | |
51 assert(result != NULL); | |
52 free(result); | |
53 return false; | |
54 } | 39 } |
55 | 40 |
56 for (int i = 0; i < length / sizeof(*result); i++) { | 41 for (int i = 0; i < size / sizeof(*pids); i++) { |
57 const pid_t pid = result[i].kp_proc.p_pid; | 42 const pid_t pid = pids[i].kp_proc.p_pid; |
58 if (!process_proc({pid, GetProcessName(pid)})) | 43 if (!process_proc({pid, GetProcessName(pid)})) |
59 return false; | 44 return false; |
60 } | 45 } |
61 | 46 |
62 return true; | 47 return true; |
79 | 64 |
80 for (int i = 0; i < bufsz / sizeof(info[0]); i++) { | 65 for (int i = 0; i < bufsz / sizeof(info[0]); i++) { |
81 if (info[i].proc_fdtype == PROX_FDTYPE_VNODE) { | 66 if (info[i].proc_fdtype == PROX_FDTYPE_VNODE) { |
82 struct vnode_fdinfowithpath vnodeInfo; | 67 struct vnode_fdinfowithpath vnodeInfo; |
83 | 68 |
84 int sz = proc_pidfdinfo(pid, info[i].proc_fd, PROC_PIDFDVNODEPATHINFO, &vnodeInfo, PROC_PIDFDVNODEPATHINFO_SIZE); | 69 int sz = proc_pidfdinfo(pid, info[i].proc_fd, PROC_PIDFDVNODEPATHINFO, &vnodeInfo, |
70 PROC_PIDFDVNODEPATHINFO_SIZE); | |
85 if (sz != PROC_PIDFDVNODEPATHINFO_SIZE) | 71 if (sz != PROC_PIDFDVNODEPATHINFO_SIZE) |
86 return false; | 72 return false; |
87 | 73 |
88 /* this doesn't work! | 74 /* this doesn't work! |
89 if (vnodeInfo.pfi.fi_openflags & O_WRONLY || vnodeInfo.pfi.fi_openflags & O_RDWR) | 75 if (vnodeInfo.pfi.fi_openflags & O_WRONLY || vnodeInfo.pfi.fi_openflags & O_RDWR) |
90 continue; | 76 continue; |
91 */ | 77 */ |
92 | 78 |
93 if (!open_file_proc({pid, vnodeInfo.pvip.vip_path})) | 79 if (!open_file_proc({pid, vnodeInfo.pvip.vip_path})) |
94 return false; | 80 return false; |
95 } | 81 } |
97 } | 83 } |
98 | 84 |
99 return true; | 85 return true; |
100 } | 86 } |
101 | 87 |
102 } // namespace animia::internal::unix | 88 } // namespace animia::internal::xnu |