258
|
1 #include "animone/fd/xnu.h"
|
|
2 #include "animone.h"
|
|
3 #include "animone/util/osx.h"
|
|
4
|
|
5 #include <cassert>
|
|
6 #include <memory>
|
|
7 #include <string>
|
|
8 #include <unordered_map>
|
|
9 #include <vector>
|
|
10
|
|
11 #include <fcntl.h>
|
|
12 #include <libproc.h>
|
|
13 #include <sys/sysctl.h>
|
|
14 #include <sys/types.h>
|
|
15 #include <sys/user.h>
|
|
16
|
|
17 namespace animone::internal::xnu {
|
|
18
|
|
19 bool EnumerateOpenProcesses(process_proc_t process_proc) {
|
|
20 size_t pids_size = 256;
|
|
21 std::unique_ptr<pid_t[]> pids;
|
|
22
|
|
23 int returned_size = 0;
|
|
24 do {
|
|
25 pids.reset(new pid_t[pids_size *= 2]);
|
|
26 returned_size = proc_listpids(PROC_ALL_PIDS, 0, pids.get(), pids_size * sizeof(pid_t));
|
|
27 if (returned_size == -1)
|
|
28 return false;
|
|
29 } while ((pids_size * sizeof(size_t)) < returned_size);
|
|
30
|
|
31 for (int i = 0; i < pids_size; i++) {
|
|
32 std::string result;
|
|
33 osx::util::GetProcessName(pids[i], result);
|
|
34 if (!process_proc({pids[i], result}))
|
|
35 return false;
|
|
36 }
|
|
37
|
|
38 return true;
|
|
39 }
|
|
40
|
|
41 bool EnumerateOpenFiles(const std::set<pid_t>& pids, open_file_proc_t open_file_proc) {
|
|
42 if (!open_file_proc)
|
|
43 return false;
|
|
44
|
|
45 for (const auto& pid : pids) {
|
|
46 const int bufsz = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0);
|
|
47 if (bufsz < 0)
|
|
48 return false;
|
|
49
|
|
50 const size_t info_len = bufsz / sizeof(struct proc_fdinfo);
|
|
51 if (info_len < 1)
|
|
52 return false;
|
|
53
|
|
54 std::unique_ptr<struct proc_fdinfo[]> info(new struct proc_fdinfo[info_len]);
|
|
55 if (!info)
|
|
56 return false;
|
|
57
|
|
58 proc_pidinfo(pid, PROC_PIDLISTFDS, 0, info.get(), bufsz);
|
|
59
|
|
60 for (size_t i = 0; i < info_len; i++) {
|
|
61 if (info[i].proc_fdtype == PROX_FDTYPE_VNODE) {
|
|
62 struct vnode_fdinfowithpath vnodeInfo;
|
|
63
|
|
64 int sz = proc_pidfdinfo(pid, info[i].proc_fd, PROC_PIDFDVNODEPATHINFO, &vnodeInfo,
|
|
65 PROC_PIDFDVNODEPATHINFO_SIZE);
|
|
66 if (sz != PROC_PIDFDVNODEPATHINFO_SIZE)
|
|
67 return false;
|
|
68
|
|
69 // This doesn't work (for unknown reasons). I assume somethings fucked up with
|
|
70 // my assumptions; I don't care enough to look into it tbh
|
|
71 //
|
|
72 // if (vnodeInfo.pfi.fi_openflags & O_WRONLY || vnodeInfo.pfi.fi_openflags & O_RDWR)
|
|
73 // continue;
|
|
74
|
|
75 if (!open_file_proc({pid, vnodeInfo.pvip.vip_path}))
|
|
76 return false;
|
|
77 }
|
|
78 }
|
|
79 }
|
|
80
|
|
81 return true;
|
|
82 }
|
|
83
|
|
84 } // namespace animone::internal::xnu
|