Mercurial > minori
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; }