comparison 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
comparison
equal deleted inserted replaced
77:6f7385bd334c 78:1ce00c1c8ddc
7 #include <string> 7 #include <string>
8 #include <sys/stat.h> 8 #include <sys/stat.h>
9 #include <unistd.h> 9 #include <unistd.h>
10 #include <unordered_map> 10 #include <unordered_map>
11 #include <vector> 11 #include <vector>
12 #include <cstring>
13 #include <dirent.h>
12 14
13 #define PROC_LOCATION "/proc" 15 #define PROC_LOCATION "/proc"
14 16
15 namespace Animia::Linux { 17 namespace Animia::Linux {
16 18
19 std::vector<std::string> get_all_files_in_dir(const std::string& _dir) {
20 std::vector<std::string> ret;
21
22 DIR* dir = opendir(_dir.c_str());
23 if (!dir)
24 return ret;
25
26 struct dirent* dp;
27 while ((dp = readdir(dir)) != NULL) {
28 if (!(!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")))
29 ret.push_back(_dir + "/" + dp->d_name);
30 }
31
32 closedir(dir);
33 return ret;
34 }
35
36 std::string basename(const std::string& path) {
37 return path.substr(path.find_last_of("/") + 1, path.length());
38 }
39
40 std::string stem(const std::string& path) {
41 std::string bn = basename(path);
42 return bn.substr(0, path.find_last_of("."));
43 }
44
17 std::vector<int> get_all_pids() { 45 std::vector<int> get_all_pids() {
18 std::vector<int> ret; 46 std::vector<int> ret;
19 for (const auto& dir : std::filesystem::directory_iterator(PROC_LOCATION)) { 47
48 for (const auto& dir : get_all_files_in_dir(PROC_LOCATION)) {
20 int pid; 49 int pid;
21 try { 50 try {
22 pid = std::stoi(dir.path().stem()); 51 pid = std::stoi(basename(dir));
23 } catch (std::invalid_argument) { 52 } catch (std::invalid_argument) {
24 continue; 53 continue;
25 } 54 }
26 ret.push_back(pid); 55 ret.push_back(pid);
27 } 56 }
57
28 return ret; 58 return ret;
29 } 59 }
30 60
31 std::string get_process_name(int pid) { 61 std::string get_process_name(int pid) {
32 std::string path = PROC_LOCATION "/" + std::to_string(pid) + "/comm"; 62 std::string path = PROC_LOCATION "/" + std::to_string(pid) + "/comm";
61 if (flags & O_WRONLY || flags & O_RDWR) 91 if (flags & O_WRONLY || flags & O_RDWR)
62 return false; 92 return false;
63 return true; 93 return true;
64 } 94 }
65 95
66 static int get_size_of_link(std::string link) { 96 static std::string get_name_from_fd(std::string link) {
67 struct stat sb; 97 size_t exe_size = 1024;
68 if (lstat(link.c_str(), &sb) == -1) 98 ssize_t exe_used;
69 return -1; 99 std::string ret;
70 return sb.st_size + 1; 100 while (1) {
101 ret = std::string(exe_size, '\0');
102 exe_used = readlink(link.c_str(), &ret.front(), ret.length());
103 if (exe_used == (ssize_t)-1)
104 return NULL;
105
106 if (exe_used < (ssize_t)1) {
107 errno = ENOENT;
108 return NULL;
109 }
110
111 if (exe_used < (ssize_t)(exe_size - 1))
112 break;
113
114 exe_size += 1024;
115 }
116
117 return ret.c_str();
71 } 118 }
72 119
73 std::vector<std::string> get_open_files(int pid) { 120 std::vector<std::string> get_open_files(int pid) {
74 std::vector<std::string> ret; 121 std::vector<std::string> ret;
75 std::string path = PROC_LOCATION "/" + std::to_string(pid) + "/fd"; 122 std::string path = PROC_LOCATION "/" + std::to_string(pid) + "/fd";
76 try {
77 for (const auto& dir : std::filesystem::directory_iterator(path)) {
78 if (!are_flags_ok(pid, std::stoi(dir.path().stem())))
79 continue;
80 /* get filename size */
81 int size = get_size_of_link(dir.path().string());
82 /* allocate buffer */
83 std::string buf(size, '\0');
84 // std::string buf('\0', size);
85 /* read filename to buffer */
86 int r = readlink(dir.path().c_str(), &buf.front(), buf.length());
87 123
88 if (r < 0) 124 for (const auto& dir : get_all_files_in_dir(path)) {
89 continue; 125 if (!are_flags_ok(pid, std::stoi(basename(dir))))
90 if (!is_regular_file(buf)) 126 continue;
91 continue; 127
92 ret.push_back(buf); 128 std::string buf = get_name_from_fd(dir);
93 } 129
94 } catch (std::filesystem::filesystem_error const& ex) { 130 if (!is_regular_file(buf))
95 if (ex.code().value() != 13) // 13 == permissions error, common with /proc, ignore 131 continue;
96 throw; 132
133 ret.push_back(buf);
97 } 134 }
98 return ret; 135 return ret;
99 } 136 }
100 137
101 std::unordered_map<int, std::vector<std::string>> get_all_open_files() { 138 std::unordered_map<int, std::vector<std::string>> get_all_open_files() {