| 112 | std::vector<PIDInfo> PIDs; |
| 113 | |
| 114 | int main(int argc, char** argv) { |
| 115 | Config::LoadOptions(argc, argv); |
| 116 | |
| 117 | // Iterate over all pids, storing the data for investigating afterwards. |
| 118 | for (const auto& Entry : std::filesystem::directory_iterator("/proc/")) { |
| 119 | // If not a directory then skip. |
| 120 | if (!Entry.is_directory()) { |
| 121 | continue; |
| 122 | } |
| 123 | |
| 124 | auto CMDLinePath = Entry.path() / "cmdline"; |
| 125 | auto StatusPath = Entry.path() / "status"; |
| 126 | auto ExePath = Entry.path() / "exe"; |
| 127 | |
| 128 | // If cmdline doesn't exist then skip. |
| 129 | if (!std::filesystem::exists(CMDLinePath)) { |
| 130 | continue; |
| 131 | } |
| 132 | |
| 133 | auto Filename = Entry.path().filename().string(); |
| 134 | int64_t pid; |
| 135 | auto ConvResult = std::from_chars(Filename.data(), Filename.data() + Filename.size(), pid, 10); |
| 136 | |
| 137 | // If the filename couldn't be converted to a PID then skip. |
| 138 | // Happens with folders like `self` and a few other folders in this directory. |
| 139 | if (ConvResult.ec == std::errc::invalid_argument) { |
| 140 | continue; |
| 141 | } |
| 142 | |
| 143 | std::ostringstream CMDLineData; |
| 144 | { |
| 145 | std::ifstream fs(CMDLinePath, std::ios_base::in | std::ios_base::binary); |
| 146 | |
| 147 | if (!fs.is_open()) { |
| 148 | continue; |
| 149 | } |
| 150 | |
| 151 | CMDLineData << fs.rdbuf(); |
| 152 | |
| 153 | // If cmdline was empty then skip. |
| 154 | if (CMDLineData.str().empty()) { |
| 155 | continue; |
| 156 | } |
| 157 | } |
| 158 | |
| 159 | std::error_code ec; |
| 160 | std::string exe_link = std::filesystem::read_symlink(ExePath, ec); |
| 161 | |
| 162 | // Couldn't read exe path? skip. |
| 163 | if (ec) { |
| 164 | continue; |
| 165 | } |
| 166 | |
| 167 | // Read state |
| 168 | char State {}; |
| 169 | |
| 170 | { |
| 171 | std::ifstream fs(StatusPath, std::ios_base::in | std::ios_base::binary); |
nothing calls this directly
no test coverage detected