Mercurial > minori
annotate dep/animia/src/linux.cpp @ 56:6ff7aabeb9d7
deps: add animia for open files detection
author | Paper <mrpapersonic@gmail.com> |
---|---|
date | Thu, 28 Sep 2023 12:35:21 -0400 |
parents | |
children | 4c6dd5999b39 |
rev | line source |
---|---|
56
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
1 #include <string> |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
2 #include <vector> |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
3 #include <fstream> |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
4 #include <filesystem> |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
5 #include <unordered_map> |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
6 #include <iostream> |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
7 #include <sstream> |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
8 #include <unistd.h> |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
9 #include <sys/stat.h> |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
10 #include <fcntl.h> |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
11 #include <algorithm> |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
12 |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
13 #define PROC_LOCATION "/proc" |
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 namespace Animia::Linux { |
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 std::vector<int> get_all_pids() { |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
18 std::vector<int> ret; |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
19 for (const auto& dir : std::filesystem::directory_iterator(PROC_LOCATION)) { |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
20 int pid; |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
21 try { |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
22 pid = std::stoi(dir.path().stem()); |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
23 } catch (std::invalid_argument) { |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
24 continue; |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
25 } |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
26 ret.push_back(pid); |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
27 } |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
28 return ret; |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
29 } |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
30 |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
31 std::string get_process_name(int pid) { |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
32 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
|
33 std::ifstream t(path); |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
34 std::stringstream buf; |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
35 buf << t.rdbuf(); |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
36 std::string str = buf.str(); |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
37 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
|
38 return str; |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
39 } |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
40 |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
41 static bool is_regular_file(std::string link) { |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
42 struct stat sb; |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
43 if (stat(link.c_str(), &sb) == -1) |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
44 return false; |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
45 return S_ISREG(sb.st_mode); |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
46 } |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
47 |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
48 static bool are_flags_ok(int pid, int fd) { |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
49 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
|
50 std::ifstream t(path); |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
51 std::stringstream buffer; |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
52 buffer << t.rdbuf(); |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
53 std::string raw; |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
54 int flags = 0; |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
55 while (std::getline(buffer, raw)) { |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
56 if (raw.rfind("flags:", 0) == 0) { |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
57 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
|
58 } |
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 if (flags & O_WRONLY || flags & O_RDWR) |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
61 return false; |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
62 return true; |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
63 } |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
64 |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
65 static int get_size_of_link(std::string link) { |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
66 struct stat sb; |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
67 if (lstat(link.c_str(), &sb) == -1) |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
68 return -1; |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
69 return sb.st_size + 1; |
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 std::vector<std::string> get_open_files(int pid) { |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
73 std::vector<std::string> ret; |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
74 std::string path = PROC_LOCATION "/" + std::to_string(pid) + "/fd"; |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
75 try { |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
76 for (const auto& dir : std::filesystem::directory_iterator(path)) { |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
77 if (!are_flags_ok(pid, std::stoi(dir.path().stem()))) |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
78 continue; |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
79 /* get filename size */ |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
80 int size = get_size_of_link(dir.path().string()); |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
81 /* allocate buffer */ |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
82 char* buf = (char*)calloc(size, sizeof(char)); |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
83 //std::string buf('\0', size); |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
84 /* read filename to buffer */ |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
85 int r = readlink(dir.path().c_str(), buf, size); |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
86 |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
87 if (r < 0) |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
88 continue; |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
89 if (!is_regular_file(buf)) |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
90 continue; |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
91 ret.push_back(buf); |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
92 free(buf); |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
93 } |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
94 } catch (std::filesystem::filesystem_error const& ex) { |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
95 if (ex.code().value() != 13) // 13 == permissions error, common with /proc, ignore |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
96 throw; |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
97 } |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
98 return ret; |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
99 } |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
100 |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
101 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
|
102 std::unordered_map<int, std::vector<std::string>> map; |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
103 std::vector<int> pids = get_all_pids(); |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
104 for (int i: pids) |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
105 map[i] = get_open_files(i); |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
106 return map; |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
107 } |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
108 |
6ff7aabeb9d7
deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
109 } |