annotate dep/animone/src/fd/xnu.cc @ 337:a7d4e5107531

dep/animone: REFACTOR ALL THE THINGS 1: animone now has its own syntax divergent from anisthesia, making different platforms actually have their own sections 2: process names in animone are now called `comm' (this will probably break things). this is what its called in bsd/linux so I'm just going to use it everywhere 3: the X11 code now checks for the existence of a UTF-8 window title and passes it if available 4: ANYTHING THATS NOT LINUX IS 100% UNTESTED AND CAN AND WILL BREAK! I still actually need to test the bsd code. to be honest I'm probably going to move all of the bsds into separate files because they're all essentially different operating systems at this point
author Paper <paper@paper.us.eu.org>
date Wed, 19 Jun 2024 12:51:15 -0400
parents a4257370de16
children f81bed4e04ac
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
310
a4257370de16 dep/animone: prepare for v1.0 release; it should be ready by now
Paper <paper@paper.us.eu.org>
parents: 301
diff changeset
1 /*
a4257370de16 dep/animone: prepare for v1.0 release; it should be ready by now
Paper <paper@paper.us.eu.org>
parents: 301
diff changeset
2 * fd/xnu.cc: support for macOS's kernel
a4257370de16 dep/animone: prepare for v1.0 release; it should be ready by now
Paper <paper@paper.us.eu.org>
parents: 301
diff changeset
3 *
a4257370de16 dep/animone: prepare for v1.0 release; it should be ready by now
Paper <paper@paper.us.eu.org>
parents: 301
diff changeset
4 * this used to have all sorts of hacks for getting the process name,
a4257370de16 dep/animone: prepare for v1.0 release; it should be ready by now
Paper <paper@paper.us.eu.org>
parents: 301
diff changeset
5 * but ultimately I just decided that it's better to just parse the
a4257370de16 dep/animone: prepare for v1.0 release; it should be ready by now
Paper <paper@paper.us.eu.org>
parents: 301
diff changeset
6 * PID path from xnu, which should work perfectly fine.
a4257370de16 dep/animone: prepare for v1.0 release; it should be ready by now
Paper <paper@paper.us.eu.org>
parents: 301
diff changeset
7 */
301
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
8 #include "animone/fd/xnu.h"
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
9 #include "animone.h"
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 <cassert>
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
12 #include <memory>
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
13 #include <string>
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
14 #include <unordered_map>
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
15 #include <vector>
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 #include <fcntl.h>
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
18 #include <libproc.h>
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
19 #include <sys/sysctl.h>
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
20 #include <sys/types.h>
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
21 #include <sys/user.h>
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 /* you may be asking: WTF is FWRITE?
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
24 * 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
25 *
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
26 * 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
27 * 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
28 *
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
29 * 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
30 */
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
31 #ifndef FWRITE
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
32 #define FWRITE 0x0002
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
33 #endif
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 namespace animone::internal::xnu {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
36
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
37 bool EnumerateOpenProcesses(process_proc_t process_proc) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
38 size_t pids_size = 256;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
39 std::unique_ptr<pid_t[]> pids;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
40
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
41 int returned_size = 0;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
42 do {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
43 pids.reset(new pid_t[pids_size *= 2]);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
44 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
45 if (returned_size == -1)
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
46 return false;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
47 } while ((pids_size * sizeof(size_t)) < returned_size);
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 for (int i = 0; i < pids_size; i++) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
50 std::string result;
337
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
51 GetProcessName(pids[i], result);
a7d4e5107531 dep/animone: REFACTOR ALL THE THINGS
Paper <paper@paper.us.eu.org>
parents: 310
diff changeset
52 if (!process_proc({.platform = ExecutablePlatform::Xnu, .pid = pids[i], .comm = result}))
301
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
53 return false;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
54 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
55
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
56 return true;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
57 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
58
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
59 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
60 if (!open_file_proc)
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
61 return false;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
62
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
63 for (const auto& pid : pids) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
64 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
65 if (bufsz < 0)
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
66 return false;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
67
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
68 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
69 if (info_len < 1)
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
70 return false;
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 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
73 if (!info)
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
74 return false;
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 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
77
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
78 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
79 if (info[i].proc_fdtype == PROX_FDTYPE_VNODE) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
80 struct vnode_fdinfowithpath vnodeInfo;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
81
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
82 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
83 PROC_PIDFDVNODEPATHINFO_SIZE);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
84 if (sz != PROC_PIDFDVNODEPATHINFO_SIZE)
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
85 return false;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
86
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
87 /* 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
88 if (vnodeInfo.pfi.fi_openflags & FWRITE)
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
89 continue;
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 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
92 return false;
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 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
95 }
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 return true;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
98 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
99
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
100 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
101 result.assign(PROC_PIDPATHINFO_MAXSIZE, '\0');
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
102
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
103 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
104 if (ret <= 0)
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
105 return false;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
106
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
107 /* 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
108 size_t last_slash = result.rfind('/');
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
109 if (last_slash == std::string::npos)
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
110 return true;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
111
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
112 result.erase(0, last_slash + 1);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
113 return true;
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
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
116 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
117 result.assign(2 * MAXCOMLEN, '\0');
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
118
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
119 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
120
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
121 /* if size is MAXCOMLEN or 2 * MAXCOMLEN, assume
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
122 * 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
123 if (size <= 0 || size == MAXCOMLEN || size == 2 * MAXCOMLEN)
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
124 return false;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
125
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
126 result.resize(size);
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
127 return true;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
128 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
129
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
130 bool GetProcessName(pid_t pid, std::string& result) {
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
131 if (GetProcessNameFromProcName(pid, result))
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
132 return true;
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 if (GetProcessNameFromProcPidPath(pid, result))
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
135 return true;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
136
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
137 return false;
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
138 }
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
139
b1f625b0227c *: convert all files CRLF -> LF
Paper <paper@paper.us.eu.org>
parents: 299
diff changeset
140 } // namespace animone::internal::xnu