Mercurial > minori
view dep/animia/src/linux.cpp @ 118:39521c47c7a3
*: another huge megacommit, SORRY
The torrents page works a lot better now
Added the edit option to the anime list right click menu
Vectorized currently playing files
Available player and extensions are now loaded at runtime
from files in (dotpath)/players.json and (dotpath)/extensions.json
These paths are not permanent and will likely be moved to
(dotpath)/recognition
...
...
...
author | Paper <mrpapersonic@gmail.com> |
---|---|
date | Tue, 07 Nov 2023 23:40:54 -0500 |
parents | eab9e623eb84 |
children |
line wrap: on
line source
#include <algorithm> #include <fcntl.h> #include <filesystem> #include <fstream> #include <iostream> #include <sstream> #include <string> #include <sys/stat.h> #include <unistd.h> #include <unordered_map> #include <vector> #include <cstring> #include <dirent.h> #define PROC_LOCATION "/proc" namespace Animia { namespace 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 : get_all_files_in_dir(PROC_LOCATION)) { int pid; try { pid = std::stoi(basename(dir)); } catch (std::invalid_argument) { continue; } ret.push_back(pid); } return ret; } std::string get_process_name(int pid) { std::string path = PROC_LOCATION "/" + std::to_string(pid) + "/comm"; std::ifstream t(path); std::stringstream buf; buf << t.rdbuf(); std::string str = buf.str(); str.erase(std::remove(str.begin(), str.end(), '\n'), str.end()); return str; } static bool is_regular_file(std::string link) { struct stat sb; if (stat(link.c_str(), &sb) == -1) return false; return S_ISREG(sb.st_mode); } static bool are_flags_ok(int pid, int fd) { std::string path = PROC_LOCATION "/" + std::to_string(pid) + "/fdinfo/" + std::to_string(fd); std::ifstream t(path); std::stringstream buffer; buffer << t.rdbuf(); std::string raw; int flags = 0; while (std::getline(buffer, raw)) { if (raw.rfind("flags:", 0) == 0) { flags = std::stoi(raw.substr(raw.find_last_not_of("0123456789") + 1)); } } if (flags & O_WRONLY || flags & O_RDWR) return false; return true; } 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"; for (const auto& dir : get_all_files_in_dir(path)) { if (!are_flags_ok(pid, std::stoi(basename(dir)))) continue; std::string buf = get_name_from_fd(dir); if (!is_regular_file(buf)) continue; ret.push_back(buf); } return ret; } std::unordered_map<int, std::vector<std::string>> get_all_open_files() { std::unordered_map<int, std::vector<std::string>> map; std::vector<int> pids = get_all_pids(); for (int i : pids) map[i] = get_open_files(i); return map; } } // namespace Linux } // namespace Animia