annotate src/fd/xnu.cc @ 21:973734ebd2be

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