Mercurial > minori
annotate dep/animia/src/fd/proc.cc @ 198:bc1ae1810855
dep/animia: switch from using classes to global functions
the old idea was ok, but sort of hackish; this method doesn't use classes
at all, and this way (especially important!) we can do wayland stuff AND x11
at the same time, which wasn't really possible without stupid workarounds in
the other method
author | Paper <mrpapersonic@gmail.com> |
---|---|
date | Sun, 24 Dec 2023 02:59:42 -0500 |
parents | c413e475f496 |
children | 031a257ee019 |
rev | line source |
---|---|
166 | 1 #include "animia/fd/proc.h" |
152
8700806c2cc2
dep/animia: awesome new breaking changes!
Paper <mrpapersonic@gmail.com>
parents:
151
diff
changeset
|
2 #include "animia.h" |
156
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
154
diff
changeset
|
3 #include "animia/util.h" |
140
1e696863b54c
dep/animia: remove superfluous includes
Paper <mrpapersonic@gmail.com>
parents:
139
diff
changeset
|
4 |
138
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
5 #include <algorithm> |
156
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
154
diff
changeset
|
6 #include <cstring> |
138
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
7 #include <filesystem> |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
8 #include <fstream> |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
9 #include <sstream> |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
10 #include <string> |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
11 #include <unordered_map> |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
12 #include <vector> |
140
1e696863b54c
dep/animia: remove superfluous includes
Paper <mrpapersonic@gmail.com>
parents:
139
diff
changeset
|
13 |
156
cdf79282d647
dep/animia: add VERY early x11 window stuff
Paper <mrpapersonic@gmail.com>
parents:
154
diff
changeset
|
14 #include <dirent.h> |
140
1e696863b54c
dep/animia: remove superfluous includes
Paper <mrpapersonic@gmail.com>
parents:
139
diff
changeset
|
15 #include <fcntl.h> |
1e696863b54c
dep/animia: remove superfluous includes
Paper <mrpapersonic@gmail.com>
parents:
139
diff
changeset
|
16 #include <sys/stat.h> |
1e696863b54c
dep/animia: remove superfluous includes
Paper <mrpapersonic@gmail.com>
parents:
139
diff
changeset
|
17 #include <unistd.h> |
138
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
18 |
181
d26cd2c00270
dep/animia/fd/proc: use constexpr std::string_view for proc location
Paper <mrpapersonic@gmail.com>
parents:
180
diff
changeset
|
19 static constexpr std::string_view PROC_LOCATION = "/proc"; |
138
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
20 |
166 | 21 namespace animia::internal::proc { |
138
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
22 |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
23 /* this uses dirent instead of std::filesystem; it would make a bit |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
24 more sense to use the latter, but this is platform dependent already :) */ |
163
44c5e6dd9488
dep/animia/osx: move GetProcessName to util/osx so we can use it in quartz
Paper <mrpapersonic@gmail.com>
parents:
156
diff
changeset
|
25 static std::vector<std::string> GetAllFilesInDir(const std::string& _dir) { |
138
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
26 std::vector<std::string> ret; |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
27 |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
28 DIR* dir = opendir(_dir.c_str()); |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
29 if (!dir) |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
30 return ret; |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
31 |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
32 struct dirent* dp; |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
33 while ((dp = readdir(dir)) != NULL) { |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
34 if (!(!strcmp(dp->d_name, ".") || !strcmp(dp->d_name, ".."))) |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
35 ret.push_back(_dir + "/" + dp->d_name); |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
36 } |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
37 |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
38 closedir(dir); |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
39 return ret; |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
40 } |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
41 |
163
44c5e6dd9488
dep/animia/osx: move GetProcessName to util/osx so we can use it in quartz
Paper <mrpapersonic@gmail.com>
parents:
156
diff
changeset
|
42 static std::string Basename(const std::string& path) { |
138
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
43 return path.substr(path.find_last_of("/") + 1, path.length()); |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
44 } |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
45 |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
46 static bool IsRegularFile(std::string link) { |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
47 struct stat sb; |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
48 if (stat(link.c_str(), &sb) == -1) |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
49 return false; |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
50 return S_ISREG(sb.st_mode); |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
51 } |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
52 |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
53 static bool AreFlagsOk(pid_t pid, int fd) { |
181
d26cd2c00270
dep/animia/fd/proc: use constexpr std::string_view for proc location
Paper <mrpapersonic@gmail.com>
parents:
180
diff
changeset
|
54 const std::string path = std::string(PROC_LOCATION) + "/" + std::to_string(pid) + "/fdinfo/" + std::to_string(fd); |
164
99fdf5a90b0f
fd/linux: avoid reading buffers multiple times
Paper <mrpapersonic@gmail.com>
parents:
163
diff
changeset
|
55 |
99fdf5a90b0f
fd/linux: avoid reading buffers multiple times
Paper <mrpapersonic@gmail.com>
parents:
163
diff
changeset
|
56 std::ifstream file(path.c_str()); |
99fdf5a90b0f
fd/linux: avoid reading buffers multiple times
Paper <mrpapersonic@gmail.com>
parents:
163
diff
changeset
|
57 if (!file) |
99fdf5a90b0f
fd/linux: avoid reading buffers multiple times
Paper <mrpapersonic@gmail.com>
parents:
163
diff
changeset
|
58 return false; |
138
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
59 |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
60 int flags = 0; |
164
99fdf5a90b0f
fd/linux: avoid reading buffers multiple times
Paper <mrpapersonic@gmail.com>
parents:
163
diff
changeset
|
61 for (std::string line; std::getline(file, line); ) |
99fdf5a90b0f
fd/linux: avoid reading buffers multiple times
Paper <mrpapersonic@gmail.com>
parents:
163
diff
changeset
|
62 if (line.find("flags:", 0) == 0) |
138
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
63 flags = std::stoi(line.substr(line.find_last_not_of("0123456789") + 1)); |
164
99fdf5a90b0f
fd/linux: avoid reading buffers multiple times
Paper <mrpapersonic@gmail.com>
parents:
163
diff
changeset
|
64 |
138
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
65 if (flags & O_WRONLY || flags & O_RDWR) |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
66 return false; |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
67 return true; |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
68 } |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
69 |
166 | 70 static bool GetFilenameFromFd(std::string link, std::string& out) { |
138
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
71 /* gets around stupid linux limitation where /proc doesn't |
180
5be17d636aee
deps/animia/fd/proc: patch for new filename getter
Paper <mrpapersonic@gmail.com>
parents:
166
diff
changeset
|
72 * give actual size readings of the string |
5be17d636aee
deps/animia/fd/proc: patch for new filename getter
Paper <mrpapersonic@gmail.com>
parents:
166
diff
changeset
|
73 */ |
166 | 74 constexpr size_t OUT_MAX = (1 << 15); // 32KiB |
75 out.resize(1024); | |
138
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
76 |
166 | 77 for (ssize_t exe_used = 0; |
78 out.length() < OUT_MAX && exe_used >= (ssize_t)(out.length() - 1); | |
79 out.resize(out.length() * 2)) { | |
80 exe_used = readlink(link.c_str(), &out.front(), out.length()); | |
81 if (exe_used == (ssize_t)-1 || exe_used < (ssize_t)1) | |
180
5be17d636aee
deps/animia/fd/proc: patch for new filename getter
Paper <mrpapersonic@gmail.com>
parents:
166
diff
changeset
|
82 return false; // we got a bad result, i think |
138
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
83 } |
180
5be17d636aee
deps/animia/fd/proc: patch for new filename getter
Paper <mrpapersonic@gmail.com>
parents:
166
diff
changeset
|
84 |
182
c413e475f496
dep/animia: various stylistic changes
Paper <mrpapersonic@gmail.com>
parents:
181
diff
changeset
|
85 out.resize(out.find('\0')); |
c413e475f496
dep/animia: various stylistic changes
Paper <mrpapersonic@gmail.com>
parents:
181
diff
changeset
|
86 |
180
5be17d636aee
deps/animia/fd/proc: patch for new filename getter
Paper <mrpapersonic@gmail.com>
parents:
166
diff
changeset
|
87 return true; |
138
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
88 } |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
89 |
154 | 90 static std::string GetProcessName(pid_t pid) { |
166 | 91 std::string result; |
152
8700806c2cc2
dep/animia: awesome new breaking changes!
Paper <mrpapersonic@gmail.com>
parents:
151
diff
changeset
|
92 |
181
d26cd2c00270
dep/animia/fd/proc: use constexpr std::string_view for proc location
Paper <mrpapersonic@gmail.com>
parents:
180
diff
changeset
|
93 const std::string path = std::string(PROC_LOCATION) + "/" + std::to_string(pid) + "/comm"; |
154 | 94 |
152
8700806c2cc2
dep/animia: awesome new breaking changes!
Paper <mrpapersonic@gmail.com>
parents:
151
diff
changeset
|
95 if (!util::ReadFile(path, result)) |
154 | 96 return ""; |
152
8700806c2cc2
dep/animia: awesome new breaking changes!
Paper <mrpapersonic@gmail.com>
parents:
151
diff
changeset
|
97 |
8700806c2cc2
dep/animia: awesome new breaking changes!
Paper <mrpapersonic@gmail.com>
parents:
151
diff
changeset
|
98 result.erase(std::remove(result.begin(), result.end(), '\n'), result.end()); |
154 | 99 |
100 return result; | |
152
8700806c2cc2
dep/animia: awesome new breaking changes!
Paper <mrpapersonic@gmail.com>
parents:
151
diff
changeset
|
101 } |
8700806c2cc2
dep/animia: awesome new breaking changes!
Paper <mrpapersonic@gmail.com>
parents:
151
diff
changeset
|
102 |
198
bc1ae1810855
dep/animia: switch from using classes to global functions
Paper <mrpapersonic@gmail.com>
parents:
182
diff
changeset
|
103 bool EnumerateOpenProcesses(process_proc_t process_proc) { |
144
e6668085e24d
dep/animia: fix many bugs in the linux code
Paper <mrpapersonic@gmail.com>
parents:
143
diff
changeset
|
104 bool success = false; |
181
d26cd2c00270
dep/animia/fd/proc: use constexpr std::string_view for proc location
Paper <mrpapersonic@gmail.com>
parents:
180
diff
changeset
|
105 for (const auto& dir : GetAllFilesInDir(std::string(PROC_LOCATION))) { |
138
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
106 pid_t pid; |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
107 try { |
144
e6668085e24d
dep/animia: fix many bugs in the linux code
Paper <mrpapersonic@gmail.com>
parents:
143
diff
changeset
|
108 pid = std::stoul(Basename(dir)); |
e6668085e24d
dep/animia: fix many bugs in the linux code
Paper <mrpapersonic@gmail.com>
parents:
143
diff
changeset
|
109 success = true; |
138
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
110 } catch (std::invalid_argument) { |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
111 continue; |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
112 } |
152
8700806c2cc2
dep/animia: awesome new breaking changes!
Paper <mrpapersonic@gmail.com>
parents:
151
diff
changeset
|
113 if (!process_proc({pid, GetProcessName(pid)})) |
8700806c2cc2
dep/animia: awesome new breaking changes!
Paper <mrpapersonic@gmail.com>
parents:
151
diff
changeset
|
114 return false; |
138
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
115 } |
144
e6668085e24d
dep/animia: fix many bugs in the linux code
Paper <mrpapersonic@gmail.com>
parents:
143
diff
changeset
|
116 return success; |
138
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
117 } |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
118 |
198
bc1ae1810855
dep/animia: switch from using classes to global functions
Paper <mrpapersonic@gmail.com>
parents:
182
diff
changeset
|
119 bool EnumerateOpenFiles(const std::set<pid_t>& pids, open_file_proc_t open_file_proc) { |
152
8700806c2cc2
dep/animia: awesome new breaking changes!
Paper <mrpapersonic@gmail.com>
parents:
151
diff
changeset
|
120 if (!open_file_proc) |
144
e6668085e24d
dep/animia: fix many bugs in the linux code
Paper <mrpapersonic@gmail.com>
parents:
143
diff
changeset
|
121 return false; |
e6668085e24d
dep/animia: fix many bugs in the linux code
Paper <mrpapersonic@gmail.com>
parents:
143
diff
changeset
|
122 |
138
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
123 for (const auto& pid : pids) { |
181
d26cd2c00270
dep/animia/fd/proc: use constexpr std::string_view for proc location
Paper <mrpapersonic@gmail.com>
parents:
180
diff
changeset
|
124 const std::string path = std::string(PROC_LOCATION) + "/" + std::to_string(pid) + "/fd"; |
138
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
125 |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
126 for (const auto& dir : GetAllFilesInDir(path)) { |
144
e6668085e24d
dep/animia: fix many bugs in the linux code
Paper <mrpapersonic@gmail.com>
parents:
143
diff
changeset
|
127 if (!AreFlagsOk(pid, std::stoi(Basename(dir)))) |
138
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
128 continue; |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
129 |
180
5be17d636aee
deps/animia/fd/proc: patch for new filename getter
Paper <mrpapersonic@gmail.com>
parents:
166
diff
changeset
|
130 std::string name; |
5be17d636aee
deps/animia/fd/proc: patch for new filename getter
Paper <mrpapersonic@gmail.com>
parents:
166
diff
changeset
|
131 if (!GetFilenameFromFd(dir, name)) |
5be17d636aee
deps/animia/fd/proc: patch for new filename getter
Paper <mrpapersonic@gmail.com>
parents:
166
diff
changeset
|
132 continue; |
138
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
133 |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
134 if (!IsRegularFile(name)) |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
135 continue; |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
136 |
152
8700806c2cc2
dep/animia: awesome new breaking changes!
Paper <mrpapersonic@gmail.com>
parents:
151
diff
changeset
|
137 if (!open_file_proc({pid, name})) |
8700806c2cc2
dep/animia: awesome new breaking changes!
Paper <mrpapersonic@gmail.com>
parents:
151
diff
changeset
|
138 return false; |
138
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
139 } |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
140 } |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
141 return true; |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
142 } |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
143 |
28842a8d0c6b
dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff
changeset
|
144 } // namespace animia::internal::linux |