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