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