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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
166
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 164
diff changeset
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
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 164
diff changeset
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
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 164
diff changeset
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
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 164
diff changeset
74 constexpr size_t OUT_MAX = (1 << 15); // 32KiB
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 164
diff changeset
75 out.resize(1024);
138
28842a8d0c6b dep/animia: huge refactor (again...)
Paper <mrpapersonic@gmail.com>
parents:
diff changeset
76
166
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 164
diff changeset
77 for (ssize_t exe_used = 0;
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 164
diff changeset
78 out.length() < OUT_MAX && exe_used >= (ssize_t)(out.length() - 1);
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 164
diff changeset
79 out.resize(out.length() * 2)) {
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 164
diff changeset
80 exe_used = readlink(link.c_str(), &out.front(), out.length());
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 164
diff changeset
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
d43d68408d3c dep/animia: fix XnuFdTools
Paper <mrpapersonic@gmail.com>
parents: 152
diff changeset
90 static std::string GetProcessName(pid_t pid) {
166
54c5d80a737e dep/animia: add libutil method
paper@DavesDouble.local
parents: 164
diff changeset
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
d43d68408d3c dep/animia: fix XnuFdTools
Paper <mrpapersonic@gmail.com>
parents: 152
diff changeset
94
152
8700806c2cc2 dep/animia: awesome new breaking changes!
Paper <mrpapersonic@gmail.com>
parents: 151
diff changeset
95 if (!util::ReadFile(path, result))
154
d43d68408d3c dep/animia: fix XnuFdTools
Paper <mrpapersonic@gmail.com>
parents: 152
diff changeset
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
d43d68408d3c dep/animia: fix XnuFdTools
Paper <mrpapersonic@gmail.com>
parents: 152
diff changeset
99
d43d68408d3c dep/animia: fix XnuFdTools
Paper <mrpapersonic@gmail.com>
parents: 152
diff changeset
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