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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 }