annotate dep/animone/src/fd/xnu.cc @ 301:b1f625b0227c

*: convert all files CRLF -> LF some files were in DOS format, others were in unix. now everything (that at least is under our control) should all be the same format
author Paper <paper@paper.us.eu.org>
date Mon, 13 May 2024 15:04:51 -0400
parents 246017a7907a
children a4257370de16
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
301
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
1 #include "animone/fd/xnu.h"
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
2 #include "animone.h"
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
3 #include "animone/util/osx.h"
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
4
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
5 #include <cassert>
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
6 #include <memory>
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
7 #include <string>
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
8 #include <unordered_map>
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
9 #include <vector>
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
10
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
11 #include <fcntl.h>
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
12 #include <libproc.h>
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
13 #include <sys/sysctl.h>
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
14 #include <sys/types.h>
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
15 #include <sys/user.h>
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
16
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
17 /* you may be asking: WTF is FWRITE?
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
18 * well, from bsd/sys/fcntl.h in the XNU kernel:
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
19 *
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
20 * Kernel encoding of open mode; separate read and write bits that are
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
21 * independently testable: 1 greater than [O_RDONLY and O_WRONLY].
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
22 *
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
23 * It's just how the kernel defines write mode.
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
24 */
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
25 #ifndef FWRITE
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
26 #define FWRITE 0x0002
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
27 #endif
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
28
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
29 namespace animone::internal::xnu {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
30
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
31 bool EnumerateOpenProcesses(process_proc_t process_proc) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
32 size_t pids_size = 256;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
33 std::unique_ptr<pid_t[]> pids;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
34
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
35 int returned_size = 0;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
36 do {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
37 pids.reset(new pid_t[pids_size *= 2]);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
38 returned_size = proc_listpids(PROC_ALL_PIDS, 0, pids.get(), pids_size * sizeof(pid_t));
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
39 if (returned_size == -1)
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
40 return false;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
41 } while ((pids_size * sizeof(size_t)) < returned_size);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
42
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
43 for (int i = 0; i < pids_size; i++) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
44 std::string result;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
45 osx::util::GetProcessName(pids[i], result);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
46 if (!process_proc({pids[i], result}))
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
47 return false;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
48 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
49
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
50 return true;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
51 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
52
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
53 bool EnumerateOpenFiles(const std::set<pid_t>& pids, open_file_proc_t open_file_proc) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
54 if (!open_file_proc)
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
55 return false;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
56
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
57 for (const auto& pid : pids) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
58 const int bufsz = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
59 if (bufsz < 0)
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
60 return false;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
61
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
62 const size_t info_len = bufsz / sizeof(struct proc_fdinfo);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
63 if (info_len < 1)
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
64 return false;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
65
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
66 std::unique_ptr<struct proc_fdinfo[]> info(new struct proc_fdinfo[info_len]);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
67 if (!info)
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
68 return false;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
69
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
70 proc_pidinfo(pid, PROC_PIDLISTFDS, 0, info.get(), bufsz);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
71
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
72 for (size_t i = 0; i < info_len; i++) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
73 if (info[i].proc_fdtype == PROX_FDTYPE_VNODE) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
74 struct vnode_fdinfowithpath vnodeInfo;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
75
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
76 int sz = proc_pidfdinfo(pid, info[i].proc_fd, PROC_PIDFDVNODEPATHINFO, &vnodeInfo,
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
77 PROC_PIDFDVNODEPATHINFO_SIZE);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
78 if (sz != PROC_PIDFDVNODEPATHINFO_SIZE)
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
79 return false;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
80
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
81 /* why would a media player open a file in write mode? */
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
82 if (vnodeInfo.pfi.fi_openflags & FWRITE)
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
83 continue;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
84
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
85 if (!open_file_proc({pid, vnodeInfo.pvip.vip_path}))
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
86 return false;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
87 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
88 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
89 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
90
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
91 return true;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
92 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
93
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
94 static bool GetProcessNameFromProcPidPath(pid_t pid, std::string& result) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
95 result.assign(PROC_PIDPATHINFO_MAXSIZE, '\0');
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
96
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
97 int ret = proc_pidpath(pid, result.data(), result.size() * sizeof(char));
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
98 if (ret <= 0)
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
99 return false;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
100
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
101 /* find the last slash, if there's none, we're done here */
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
102 size_t last_slash = result.rfind('/');
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
103 if (last_slash == std::string::npos)
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
104 return true;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
105
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
106 result.erase(0, last_slash + 1);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
107 return true;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
108 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
109
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
110 static bool GetProcessNameFromProcName(pid_t pid, std::string& result) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
111 result.assign(2 * MAXCOMLEN, '\0');
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
112
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
113 int size = proc_name(pid, &result.front(), result.length());
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
114
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
115 /* if size is MAXCOMLEN or 2 * MAXCOMLEN, assume
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
116 * this method won't work and our result is truncated */
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
117 if (size <= 0 || size == MAXCOMLEN || size == 2 * MAXCOMLEN)
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
118 return false;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
119
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
120 result.resize(size);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
121 return true;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
122 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
123
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
124 bool GetProcessName(pid_t pid, std::string& result) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
125 if (GetProcessNameFromProcName(pid, result))
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
126 return true;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
127
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
128 if (GetProcessNameFromProcPidPath(pid, result))
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
129 return true;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
130
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
131 return false;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
132 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
133
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
134 } // namespace animone::internal::xnu