diff dep/animia/src/linux.cpp @ 78:1ce00c1c8ddc

dep/animia: update to upstream
author Paper <mrpapersonic@gmail.com>
date Wed, 11 Oct 2023 12:16:15 -0400
parents 4c6dd5999b39
children eab9e623eb84
line wrap: on
line diff
--- a/dep/animia/src/linux.cpp	Fri Oct 06 06:18:53 2023 -0400
+++ b/dep/animia/src/linux.cpp	Wed Oct 11 12:16:15 2023 -0400
@@ -9,22 +9,52 @@
 #include <unistd.h>
 #include <unordered_map>
 #include <vector>
+#include <cstring>
+#include <dirent.h>
 
 #define PROC_LOCATION "/proc"
 
 namespace Animia::Linux {
 
+std::vector<std::string> get_all_files_in_dir(const std::string& _dir) {
+	std::vector<std::string> ret;
+
+	DIR* dir = opendir(_dir.c_str());
+	if (!dir)
+		return ret;
+
+	struct dirent* dp;
+	while ((dp = readdir(dir)) != NULL) {
+		if (!(!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")))
+			ret.push_back(_dir + "/" + dp->d_name);
+	}
+
+	closedir(dir);
+	return ret;
+}
+
+std::string basename(const std::string& path) {
+	return path.substr(path.find_last_of("/") + 1, path.length());
+}
+
+std::string stem(const std::string& path) {
+	std::string bn = basename(path);
+	return bn.substr(0, path.find_last_of("."));
+}
+
 std::vector<int> get_all_pids() {
 	std::vector<int> ret;
-	for (const auto& dir : std::filesystem::directory_iterator(PROC_LOCATION)) {
+
+	for (const auto& dir : get_all_files_in_dir(PROC_LOCATION)) {
 		int pid;
 		try {
-			pid = std::stoi(dir.path().stem());
+			pid = std::stoi(basename(dir));
 		} catch (std::invalid_argument) {
 			continue;
 		}
 		ret.push_back(pid);
 	}
+
 	return ret;
 }
 
@@ -63,37 +93,44 @@
 	return true;
 }
 
-static int get_size_of_link(std::string link) {
-	struct stat sb;
-	if (lstat(link.c_str(), &sb) == -1)
-		return -1;
-	return sb.st_size + 1;
+static std::string get_name_from_fd(std::string link) {
+	size_t  exe_size = 1024;
+	ssize_t exe_used;
+	std::string ret;
+	while (1) {
+		ret = std::string(exe_size, '\0');
+		exe_used = readlink(link.c_str(), &ret.front(), ret.length());
+		if (exe_used == (ssize_t)-1)
+			return NULL;
+
+		if (exe_used < (ssize_t)1) {
+			errno = ENOENT;
+			return NULL;
+		}
+
+		if (exe_used < (ssize_t)(exe_size - 1))
+			break;
+
+		exe_size += 1024;
+	}
+
+	return ret.c_str();
 }
 
 std::vector<std::string> get_open_files(int pid) {
 	std::vector<std::string> ret;
 	std::string path = PROC_LOCATION "/" + std::to_string(pid) + "/fd";
-	try {
-		for (const auto& dir : std::filesystem::directory_iterator(path)) {
-			if (!are_flags_ok(pid, std::stoi(dir.path().stem())))
-				continue;
-			/* get filename size */
-			int size = get_size_of_link(dir.path().string());
-			/* allocate buffer */
-			std::string buf(size, '\0');
-			// std::string buf('\0', size);
-			/* read filename to buffer */
-			int r = readlink(dir.path().c_str(), &buf.front(), buf.length());
+
+	for (const auto& dir : get_all_files_in_dir(path)) {
+		if (!are_flags_ok(pid, std::stoi(basename(dir))))
+			continue;
 
-			if (r < 0)
-				continue;
-			if (!is_regular_file(buf))
-				continue;
-			ret.push_back(buf);
-		}
-	} catch (std::filesystem::filesystem_error const& ex) {
-		if (ex.code().value() != 13) // 13 == permissions error, common with /proc, ignore
-			throw;
+		std::string buf = get_name_from_fd(dir);
+
+		if (!is_regular_file(buf))
+			continue;
+
+		ret.push_back(buf);
 	}
 	return ret;
 }