diff 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
line wrap: on
line diff
--- a/dep/animone/src/fd/xnu.cc	Tue Jul 16 21:15:59 2024 -0400
+++ b/dep/animone/src/fd/xnu.cc	Wed Oct 02 23:06:43 2024 -0400
@@ -35,21 +35,28 @@
 namespace animone::internal::xnu {
 
 bool EnumerateOpenProcesses(process_proc_t process_proc) {
-	size_t pids_size = 256;
-	std::unique_ptr<pid_t[]> pids;
+	/* pre-allocate 256 pids */
+	std::vector<pid_t> pids(256);
+	int returned_size_bytes = 0;
+
+	for (;;) {
+		returned_size_bytes = proc_listpids(PROC_ALL_PIDS, 0, pids.data(), pids.size() * sizeof(pid_t));
+		if (returned_size_bytes <= 0) /* probably an error ? */
+			return false;
 
-	int returned_size = 0;
-	do {
-		pids.reset(new pid_t[pids_size *= 2]);
-		returned_size = proc_listpids(PROC_ALL_PIDS, 0, pids.get(), pids_size * sizeof(pid_t));
-		if (returned_size == -1)
-			return false;
-	} while ((pids_size * sizeof(size_t)) < returned_size);
+		/* break out of the loop if we have everything */
+		if ((pids.size() * sizeof(pid_t)) > returned_size_bytes)
+			break;
+
+		pids.resize(pids.size() * 2);
+	}
 
-	for (int i = 0; i < pids_size; i++) {
+	pids.resize(returned_size_bytes);
+
+	for (const auto& pid : pids) {
 		std::string result;
-		GetProcessName(pids[i], result);
-		if (!process_proc({.platform = ExecutablePlatform::Xnu, .pid = pids[i], .comm = result}))
+		GetProcessName(pid, result);
+		if (!process_proc({.platform = ExecutablePlatform::Xnu, .pid = pid, .comm = result}))
 			return false;
 	}
 
@@ -61,36 +68,41 @@
 		return false;
 
 	for (const auto& pid : pids) {
-		const int bufsz = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0);
-		if (bufsz < 0)
-			return false;
+		/* most processes probably don't even have that many files opened! */
+		std::vector<struct proc_fdinfo> fds(4);
+		int returned_size_bytes = 0;
+
+		for (;;) {
+			returned_size_bytes = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, fds.data(), fds.size());
+			if (returned_size_bytes <= 0) /* probably an error ? */
+				return false;
 
-		const size_t info_len = bufsz / sizeof(struct proc_fdinfo);
-		if (info_len < 1)
-			return false;
+			/* break out of the loop if we have everything */
+			if ((fds.size() * sizeof(struct proc_fdinfo)) > returned_size_bytes)
+				break;
 
-		std::unique_ptr<struct proc_fdinfo[]> info(new struct proc_fdinfo[info_len]);
-		if (!info)
-			return false;
+			fds.resize(fds.size() * 2);
+		}
 
-		proc_pidinfo(pid, PROC_PIDLISTFDS, 0, info.get(), bufsz);
+		fds.resize(returned_size_bytes / sizeof(struct proc_fdinfo));
 
-		for (size_t i = 0; i < info_len; i++) {
-			if (info[i].proc_fdtype == PROX_FDTYPE_VNODE) {
-				struct vnode_fdinfowithpath vnodeInfo;
+		for (const auto& fd : fds) {
+			if (fd.proc_fdtype != PROX_FDTYPE_VNODE)
+				continue;
+
+			struct vnode_fdinfowithpath vnodeInfo;
 
-				int sz = proc_pidfdinfo(pid, info[i].proc_fd, PROC_PIDFDVNODEPATHINFO, &vnodeInfo,
-				                        PROC_PIDFDVNODEPATHINFO_SIZE);
-				if (sz != PROC_PIDFDVNODEPATHINFO_SIZE)
-					return false;
+			int sz = proc_pidfdinfo(pid, fd.proc_fd, PROC_PIDFDVNODEPATHINFO, &vnodeInfo,
+			                        PROC_PIDFDVNODEPATHINFO_SIZE);
+			if (sz != PROC_PIDFDVNODEPATHINFO_SIZE)
+				return false;
 
-				/* why would a media player open a file in write mode? */
-				if (vnodeInfo.pfi.fi_openflags & FWRITE)
-					continue;
+			/* why would a media player open a file in write mode? */
+			if (vnodeInfo.pfi.fi_openflags & FWRITE)
+				continue;
 
-				if (!open_file_proc({pid, vnodeInfo.pvip.vip_path}))
-					return false;
-			}
+			if (!open_file_proc({pid, vnodeInfo.pvip.vip_path}))
+				return false;
 		}
 	}
 
@@ -100,7 +112,7 @@
 static bool GetProcessNameFromProcPidPath(pid_t pid, std::string& result) {
 	result.assign(PROC_PIDPATHINFO_MAXSIZE, '\0');
 
-	int ret = proc_pidpath(pid, result.data(), result.size() * sizeof(char));
+	int ret = proc_pidpath(pid, result.data(), result.size());
 	if (ret <= 0)
 		return false;
 
@@ -116,7 +128,7 @@
 static bool GetProcessNameFromProcName(pid_t pid, std::string& result) {
 	result.assign(2 * MAXCOMLEN, '\0');
 
-	int size = proc_name(pid, &result.front(), result.length());
+	int size = proc_name(pid, result.data(), result.length());
 
 	/* if size is MAXCOMLEN or 2 * MAXCOMLEN, assume
 	 * this method won't work and our result is truncated */