annotate dep/animia/src/platform/linux/fd.cc @ 137:69db40272acd

dep/animia: [WIP] huge refactor this WILL NOT compile, because lots of code has been changed and every API in the original codebase has been removed. note that this api setup is not exactly permanent...
author Paper <mrpapersonic@gmail.com>
date Fri, 10 Nov 2023 13:52:47 -0500
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
137
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
1 #include <algorithm>
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
2 #include <fcntl.h>
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
3 #include <filesystem>
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
4 #include <fstream>
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
5 #include <iostream>
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
6 #include <sstream>
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
7 #include <string>
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
8 #include <sys/stat.h>
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
9 #include <unistd.h>
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
10 #include <unordered_map>
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
11 #include <vector>
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
12 #include <cstring>
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
13 #include <dirent.h>
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
14
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
15 #define PROC_LOCATION "/proc"
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
16
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
17 namespace Animia { namespace Linux {
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
18
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
19 std::vector<std::string> get_all_files_in_dir(const std::string& _dir) {
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
20 std::vector<std::string> ret;
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
21
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
22 DIR* dir = opendir(_dir.c_str());
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
23 if (!dir)
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
24 return ret;
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
25
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
26 struct dirent* dp;
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
27 while ((dp = readdir(dir)) != NULL) {
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
28 if (!(!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, "..")))
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
29 ret.push_back(_dir + "/" + dp->d_name);
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
30 }
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
31
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
32 closedir(dir);
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
33 return ret;
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
34 }
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
35
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
36 std::string basename(const std::string& path) {
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
37 return path.substr(path.find_last_of("/") + 1, path.length());
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
38 }
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
39
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
40 std::string stem(const std::string& path) {
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
41 std::string bn = basename(path);
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
42 return bn.substr(0, path.find_last_of("."));
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
43 }
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
44
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
45 std::vector<int> get_all_pids() {
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
46 std::vector<int> ret;
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
47
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
48 for (const auto& dir : get_all_files_in_dir(PROC_LOCATION)) {
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
49 int pid;
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
50 try {
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
51 pid = std::stoi(basename(dir));
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
52 } catch (std::invalid_argument) {
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
53 continue;
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
54 }
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
55 ret.push_back(pid);
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
56 }
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
57
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
58 return ret;
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
59 }
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
60
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
61 std::string get_process_name(int pid) {
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
62 std::string path = PROC_LOCATION "/" + std::to_string(pid) + "/comm";
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
63 std::ifstream t(path);
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
64 std::stringstream buf;
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
65 buf << t.rdbuf();
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
66
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
67 std::string str = buf.str();
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
68 str.erase(std::remove(str.begin(), str.end(), '\n'), str.end());
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
69 return str;
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
70 }
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
71
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
72 static bool is_regular_file(std::string link) {
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
73 struct stat sb;
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
74 if (stat(link.c_str(), &sb) == -1)
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
75 return false;
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
76 return S_ISREG(sb.st_mode);
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
77 }
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
78
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
79 static bool are_flags_ok(int pid, int fd) {
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
80 std::string path = PROC_LOCATION "/" + std::to_string(pid) + "/fdinfo/" + std::to_string(fd);
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
81 std::ifstream t(path);
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
82 std::stringstream buffer;
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
83 buffer << t.rdbuf();
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
84 std::string raw;
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
85 int flags = 0;
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
86 while (std::getline(buffer, raw)) {
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
87 if (raw.rfind("flags:", 0) == 0) {
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
88 flags = std::stoi(raw.substr(raw.find_last_not_of("0123456789") + 1));
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
89 }
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
90 }
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
91 if (flags & O_WRONLY || flags & O_RDWR)
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
92 return false;
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
93 return true;
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
94 }
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
95
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
96 static std::string get_name_from_fd(std::string link) {
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
97 size_t exe_size = 1024;
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
98 ssize_t exe_used;
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
99 std::string ret;
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
100 while (1) {
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
101 ret = std::string(exe_size, '\0');
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
102 exe_used = readlink(link.c_str(), &ret.front(), ret.length());
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
103 if (exe_used == (ssize_t)-1)
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
104 return NULL;
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
105
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
106 if (exe_used < (ssize_t)1) {
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
107 errno = ENOENT;
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
108 return NULL;
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
109 }
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
110
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
111 if (exe_used < (ssize_t)(exe_size - 1))
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
112 break;
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
113
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
114 exe_size += 1024;
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
115 }
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
116
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
117 return ret.c_str();
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
118 }
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
119
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
120 std::vector<std::string> get_open_files(int pid) {
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
121 std::vector<std::string> ret;
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
122 std::string path = PROC_LOCATION "/" + std::to_string(pid) + "/fd";
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
123
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
124 for (const auto& dir : get_all_files_in_dir(path)) {
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
125 if (!are_flags_ok(pid, std::stoi(basename(dir))))
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
126 continue;
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
127
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
128 std::string buf = get_name_from_fd(dir);
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
129
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
130 if (!is_regular_file(buf))
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
131 continue;
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
132
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
133 ret.push_back(buf);
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
134 }
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
135 return ret;
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
136 }
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
137
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
138 std::unordered_map<int, std::vector<std::string>> get_all_open_files() {
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
139 std::unordered_map<int, std::vector<std::string>> map;
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
140 std::vector<int> pids = get_all_pids();
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
141 for (int i : pids)
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
142 map[i] = get_open_files(i);
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
143 return map;
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
144 }
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
145
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
146 } // namespace Linux
69db40272acd dep/animia: [WIP] huge refactor
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
147 } // namespace Animia