Mercurial > minori
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() { |