annotate dep/animia/src/linux.cpp @ 62:4c6dd5999b39

*: update 1. updated animia 2. use widestrings for filesystem on Windows
author Paper <mrpapersonic@gmail.com>
date Sun, 01 Oct 2023 06:16:06 -0400
parents 6ff7aabeb9d7
children 1ce00c1c8ddc
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>
56
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();
62
4c6dd5999b39 *: update
Paper <mrpapersonic@gmail.com>
parents: 56
diff changeset
36
56
6ff7aabeb9d7 deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
37 std::string str = buf.str();
6ff7aabeb9d7 deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
38 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
39 return str;
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
6ff7aabeb9d7 deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
42 static bool is_regular_file(std::string link) {
6ff7aabeb9d7 deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
43 struct stat sb;
6ff7aabeb9d7 deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
44 if (stat(link.c_str(), &sb) == -1)
6ff7aabeb9d7 deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
45 return false;
6ff7aabeb9d7 deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
46 return S_ISREG(sb.st_mode);
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
6ff7aabeb9d7 deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
49 static bool are_flags_ok(int pid, int fd) {
6ff7aabeb9d7 deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
50 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
51 std::ifstream t(path);
6ff7aabeb9d7 deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
52 std::stringstream buffer;
6ff7aabeb9d7 deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
53 buffer << t.rdbuf();
6ff7aabeb9d7 deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
54 std::string raw;
6ff7aabeb9d7 deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
55 int flags = 0;
6ff7aabeb9d7 deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
56 while (std::getline(buffer, raw)) {
6ff7aabeb9d7 deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
57 if (raw.rfind("flags:", 0) == 0) {
6ff7aabeb9d7 deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
58 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
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 if (flags & O_WRONLY || flags & O_RDWR)
6ff7aabeb9d7 deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
62 return false;
6ff7aabeb9d7 deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
63 return true;
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
6ff7aabeb9d7 deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
66 static int get_size_of_link(std::string link) {
6ff7aabeb9d7 deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
67 struct stat sb;
6ff7aabeb9d7 deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
68 if (lstat(link.c_str(), &sb) == -1)
6ff7aabeb9d7 deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
69 return -1;
6ff7aabeb9d7 deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
70 return sb.st_size + 1;
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
6ff7aabeb9d7 deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
73 std::vector<std::string> get_open_files(int pid) {
6ff7aabeb9d7 deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
74 std::vector<std::string> ret;
6ff7aabeb9d7 deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
75 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
76 try {
6ff7aabeb9d7 deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
77 for (const auto& dir : std::filesystem::directory_iterator(path)) {
6ff7aabeb9d7 deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
78 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
79 continue;
6ff7aabeb9d7 deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
80 /* get filename size */
6ff7aabeb9d7 deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
81 int size = get_size_of_link(dir.path().string());
6ff7aabeb9d7 deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
82 /* allocate buffer */
62
4c6dd5999b39 *: update
Paper <mrpapersonic@gmail.com>
parents: 56
diff changeset
83 std::string buf(size, '\0');
4c6dd5999b39 *: update
Paper <mrpapersonic@gmail.com>
parents: 56
diff changeset
84 // std::string buf('\0', size);
56
6ff7aabeb9d7 deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
85 /* read filename to buffer */
62
4c6dd5999b39 *: update
Paper <mrpapersonic@gmail.com>
parents: 56
diff changeset
86 int r = readlink(dir.path().c_str(), &buf.front(), buf.length());
56
6ff7aabeb9d7 deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
87
6ff7aabeb9d7 deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
88 if (r < 0)
6ff7aabeb9d7 deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
89 continue;
6ff7aabeb9d7 deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
90 if (!is_regular_file(buf))
6ff7aabeb9d7 deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
91 continue;
6ff7aabeb9d7 deps: add animia for open files detection
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
92 ret.push_back(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();
62
4c6dd5999b39 *: update
Paper <mrpapersonic@gmail.com>
parents: 56
diff changeset
104 for (int i : pids)
56
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
62
4c6dd5999b39 *: update
Paper <mrpapersonic@gmail.com>
parents: 56
diff changeset
109 } // namespace Animia::Linux