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