Mercurial > minori
annotate dep/animone/src/fd/xnu.cc @ 272:5437009cb10e
dep/animone: get macOS side building
author | Paper <paper@paper.us.eu.org> |
---|---|
date | Thu, 18 Apr 2024 16:51:35 -0400 |
parents | 0718f538c5f9 |
children | 246017a7907a |
rev | line source |
---|---|
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 | |
270
0718f538c5f9
dep/animone: filter open files by access mode
Paper <paper@paper.us.eu.org>
parents:
258
diff
changeset
|
17 /* you may be asking: WTF is FWRITE? |
0718f538c5f9
dep/animone: filter open files by access mode
Paper <paper@paper.us.eu.org>
parents:
258
diff
changeset
|
18 * well, from bsd/sys/fcntl.h in the XNU kernel: |
0718f538c5f9
dep/animone: filter open files by access mode
Paper <paper@paper.us.eu.org>
parents:
258
diff
changeset
|
19 * |
0718f538c5f9
dep/animone: filter open files by access mode
Paper <paper@paper.us.eu.org>
parents:
258
diff
changeset
|
20 * Kernel encoding of open mode; separate read and write bits that are |
0718f538c5f9
dep/animone: filter open files by access mode
Paper <paper@paper.us.eu.org>
parents:
258
diff
changeset
|
21 * independently testable: 1 greater than [O_RDONLY and O_WRONLY]. |
0718f538c5f9
dep/animone: filter open files by access mode
Paper <paper@paper.us.eu.org>
parents:
258
diff
changeset
|
22 * |
0718f538c5f9
dep/animone: filter open files by access mode
Paper <paper@paper.us.eu.org>
parents:
258
diff
changeset
|
23 * It's just how the kernel defines write mode. |
0718f538c5f9
dep/animone: filter open files by access mode
Paper <paper@paper.us.eu.org>
parents:
258
diff
changeset
|
24 */ |
0718f538c5f9
dep/animone: filter open files by access mode
Paper <paper@paper.us.eu.org>
parents:
258
diff
changeset
|
25 #ifndef FWRITE |
0718f538c5f9
dep/animone: filter open files by access mode
Paper <paper@paper.us.eu.org>
parents:
258
diff
changeset
|
26 #define FWRITE 0x0002 |
0718f538c5f9
dep/animone: filter open files by access mode
Paper <paper@paper.us.eu.org>
parents:
258
diff
changeset
|
27 #endif |
0718f538c5f9
dep/animone: filter open files by access mode
Paper <paper@paper.us.eu.org>
parents:
258
diff
changeset
|
28 |
258 | 29 namespace animone::internal::xnu { |
30 | |
31 bool EnumerateOpenProcesses(process_proc_t process_proc) { | |
32 size_t pids_size = 256; | |
33 std::unique_ptr<pid_t[]> pids; | |
34 | |
35 int returned_size = 0; | |
36 do { | |
37 pids.reset(new pid_t[pids_size *= 2]); | |
38 returned_size = proc_listpids(PROC_ALL_PIDS, 0, pids.get(), pids_size * sizeof(pid_t)); | |
39 if (returned_size == -1) | |
40 return false; | |
41 } while ((pids_size * sizeof(size_t)) < returned_size); | |
42 | |
43 for (int i = 0; i < pids_size; i++) { | |
44 std::string result; | |
45 osx::util::GetProcessName(pids[i], result); | |
46 if (!process_proc({pids[i], result})) | |
47 return false; | |
48 } | |
49 | |
50 return true; | |
51 } | |
52 | |
53 bool EnumerateOpenFiles(const std::set<pid_t>& pids, open_file_proc_t open_file_proc) { | |
54 if (!open_file_proc) | |
55 return false; | |
56 | |
57 for (const auto& pid : pids) { | |
58 const int bufsz = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0); | |
59 if (bufsz < 0) | |
60 return false; | |
61 | |
62 const size_t info_len = bufsz / sizeof(struct proc_fdinfo); | |
63 if (info_len < 1) | |
64 return false; | |
65 | |
66 std::unique_ptr<struct proc_fdinfo[]> info(new struct proc_fdinfo[info_len]); | |
67 if (!info) | |
68 return false; | |
69 | |
70 proc_pidinfo(pid, PROC_PIDLISTFDS, 0, info.get(), bufsz); | |
71 | |
72 for (size_t i = 0; i < info_len; i++) { | |
73 if (info[i].proc_fdtype == PROX_FDTYPE_VNODE) { | |
74 struct vnode_fdinfowithpath vnodeInfo; | |
75 | |
76 int sz = proc_pidfdinfo(pid, info[i].proc_fd, PROC_PIDFDVNODEPATHINFO, &vnodeInfo, | |
77 PROC_PIDFDVNODEPATHINFO_SIZE); | |
78 if (sz != PROC_PIDFDVNODEPATHINFO_SIZE) | |
79 return false; | |
80 | |
270
0718f538c5f9
dep/animone: filter open files by access mode
Paper <paper@paper.us.eu.org>
parents:
258
diff
changeset
|
81 /* why would a media player open a file in write mode? */ |
0718f538c5f9
dep/animone: filter open files by access mode
Paper <paper@paper.us.eu.org>
parents:
258
diff
changeset
|
82 if (vnodeInfo.pfi.fi_openflags & FWRITE) |
0718f538c5f9
dep/animone: filter open files by access mode
Paper <paper@paper.us.eu.org>
parents:
258
diff
changeset
|
83 continue; |
258 | 84 |
85 if (!open_file_proc({pid, vnodeInfo.pvip.vip_path})) | |
86 return false; | |
87 } | |
88 } | |
89 } | |
90 | |
91 return true; | |
92 } | |
93 | |
94 } // namespace animone::internal::xnu |