Mercurial > minori
comparison dep/animone/src/fd/xnu.cc @ 365:f81bed4e04ac
*: megacommit that probably breaks things
author | Paper <paper@paper.us.eu.org> |
---|---|
date | Wed, 02 Oct 2024 23:06:43 -0400 |
parents | a7d4e5107531 |
children |
comparison
equal
deleted
inserted
replaced
364:99c961c91809 | 365:f81bed4e04ac |
---|---|
33 #endif | 33 #endif |
34 | 34 |
35 namespace animone::internal::xnu { | 35 namespace animone::internal::xnu { |
36 | 36 |
37 bool EnumerateOpenProcesses(process_proc_t process_proc) { | 37 bool EnumerateOpenProcesses(process_proc_t process_proc) { |
38 size_t pids_size = 256; | 38 /* pre-allocate 256 pids */ |
39 std::unique_ptr<pid_t[]> pids; | 39 std::vector<pid_t> pids(256); |
40 int returned_size_bytes = 0; | |
40 | 41 |
41 int returned_size = 0; | 42 for (;;) { |
42 do { | 43 returned_size_bytes = proc_listpids(PROC_ALL_PIDS, 0, pids.data(), pids.size() * sizeof(pid_t)); |
43 pids.reset(new pid_t[pids_size *= 2]); | 44 if (returned_size_bytes <= 0) /* probably an error ? */ |
44 returned_size = proc_listpids(PROC_ALL_PIDS, 0, pids.get(), pids_size * sizeof(pid_t)); | |
45 if (returned_size == -1) | |
46 return false; | 45 return false; |
47 } while ((pids_size * sizeof(size_t)) < returned_size); | |
48 | 46 |
49 for (int i = 0; i < pids_size; i++) { | 47 /* break out of the loop if we have everything */ |
48 if ((pids.size() * sizeof(pid_t)) > returned_size_bytes) | |
49 break; | |
50 | |
51 pids.resize(pids.size() * 2); | |
52 } | |
53 | |
54 pids.resize(returned_size_bytes); | |
55 | |
56 for (const auto& pid : pids) { | |
50 std::string result; | 57 std::string result; |
51 GetProcessName(pids[i], result); | 58 GetProcessName(pid, result); |
52 if (!process_proc({.platform = ExecutablePlatform::Xnu, .pid = pids[i], .comm = result})) | 59 if (!process_proc({.platform = ExecutablePlatform::Xnu, .pid = pid, .comm = result})) |
53 return false; | 60 return false; |
54 } | 61 } |
55 | 62 |
56 return true; | 63 return true; |
57 } | 64 } |
59 bool EnumerateOpenFiles(const std::set<pid_t>& pids, open_file_proc_t open_file_proc) { | 66 bool EnumerateOpenFiles(const std::set<pid_t>& pids, open_file_proc_t open_file_proc) { |
60 if (!open_file_proc) | 67 if (!open_file_proc) |
61 return false; | 68 return false; |
62 | 69 |
63 for (const auto& pid : pids) { | 70 for (const auto& pid : pids) { |
64 const int bufsz = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0); | 71 /* most processes probably don't even have that many files opened! */ |
65 if (bufsz < 0) | 72 std::vector<struct proc_fdinfo> fds(4); |
66 return false; | 73 int returned_size_bytes = 0; |
67 | 74 |
68 const size_t info_len = bufsz / sizeof(struct proc_fdinfo); | 75 for (;;) { |
69 if (info_len < 1) | 76 returned_size_bytes = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, fds.data(), fds.size()); |
70 return false; | 77 if (returned_size_bytes <= 0) /* probably an error ? */ |
78 return false; | |
71 | 79 |
72 std::unique_ptr<struct proc_fdinfo[]> info(new struct proc_fdinfo[info_len]); | 80 /* break out of the loop if we have everything */ |
73 if (!info) | 81 if ((fds.size() * sizeof(struct proc_fdinfo)) > returned_size_bytes) |
74 return false; | 82 break; |
75 | 83 |
76 proc_pidinfo(pid, PROC_PIDLISTFDS, 0, info.get(), bufsz); | 84 fds.resize(fds.size() * 2); |
85 } | |
77 | 86 |
78 for (size_t i = 0; i < info_len; i++) { | 87 fds.resize(returned_size_bytes / sizeof(struct proc_fdinfo)); |
79 if (info[i].proc_fdtype == PROX_FDTYPE_VNODE) { | |
80 struct vnode_fdinfowithpath vnodeInfo; | |
81 | 88 |
82 int sz = proc_pidfdinfo(pid, info[i].proc_fd, PROC_PIDFDVNODEPATHINFO, &vnodeInfo, | 89 for (const auto& fd : fds) { |
83 PROC_PIDFDVNODEPATHINFO_SIZE); | 90 if (fd.proc_fdtype != PROX_FDTYPE_VNODE) |
84 if (sz != PROC_PIDFDVNODEPATHINFO_SIZE) | 91 continue; |
85 return false; | |
86 | 92 |
87 /* why would a media player open a file in write mode? */ | 93 struct vnode_fdinfowithpath vnodeInfo; |
88 if (vnodeInfo.pfi.fi_openflags & FWRITE) | |
89 continue; | |
90 | 94 |
91 if (!open_file_proc({pid, vnodeInfo.pvip.vip_path})) | 95 int sz = proc_pidfdinfo(pid, fd.proc_fd, PROC_PIDFDVNODEPATHINFO, &vnodeInfo, |
92 return false; | 96 PROC_PIDFDVNODEPATHINFO_SIZE); |
93 } | 97 if (sz != PROC_PIDFDVNODEPATHINFO_SIZE) |
98 return false; | |
99 | |
100 /* why would a media player open a file in write mode? */ | |
101 if (vnodeInfo.pfi.fi_openflags & FWRITE) | |
102 continue; | |
103 | |
104 if (!open_file_proc({pid, vnodeInfo.pvip.vip_path})) | |
105 return false; | |
94 } | 106 } |
95 } | 107 } |
96 | 108 |
97 return true; | 109 return true; |
98 } | 110 } |
99 | 111 |
100 static bool GetProcessNameFromProcPidPath(pid_t pid, std::string& result) { | 112 static bool GetProcessNameFromProcPidPath(pid_t pid, std::string& result) { |
101 result.assign(PROC_PIDPATHINFO_MAXSIZE, '\0'); | 113 result.assign(PROC_PIDPATHINFO_MAXSIZE, '\0'); |
102 | 114 |
103 int ret = proc_pidpath(pid, result.data(), result.size() * sizeof(char)); | 115 int ret = proc_pidpath(pid, result.data(), result.size()); |
104 if (ret <= 0) | 116 if (ret <= 0) |
105 return false; | 117 return false; |
106 | 118 |
107 /* find the last slash, if there's none, we're done here */ | 119 /* find the last slash, if there's none, we're done here */ |
108 size_t last_slash = result.rfind('/'); | 120 size_t last_slash = result.rfind('/'); |
114 } | 126 } |
115 | 127 |
116 static bool GetProcessNameFromProcName(pid_t pid, std::string& result) { | 128 static bool GetProcessNameFromProcName(pid_t pid, std::string& result) { |
117 result.assign(2 * MAXCOMLEN, '\0'); | 129 result.assign(2 * MAXCOMLEN, '\0'); |
118 | 130 |
119 int size = proc_name(pid, &result.front(), result.length()); | 131 int size = proc_name(pid, result.data(), result.length()); |
120 | 132 |
121 /* if size is MAXCOMLEN or 2 * MAXCOMLEN, assume | 133 /* if size is MAXCOMLEN or 2 * MAXCOMLEN, assume |
122 * this method won't work and our result is truncated */ | 134 * this method won't work and our result is truncated */ |
123 if (size <= 0 || size == MAXCOMLEN || size == 2 * MAXCOMLEN) | 135 if (size <= 0 || size == MAXCOMLEN || size == 2 * MAXCOMLEN) |
124 return false; | 136 return false; |