| 23 | static const char *const LOG_TAG = "ProcessUtils"; |
| 24 | |
| 25 | std::vector<ProcessInfo> getRunningProcessInfo() { |
| 26 | std::vector<ProcessInfo> runningProcesses; |
| 27 | std::string procPath = "/proc/"; |
| 28 | DIR *dir = opendir(procPath.c_str()); |
| 29 | if (dir == nullptr) { |
| 30 | LOGE("Failed to open %s", procPath.c_str()); |
| 31 | return {}; |
| 32 | } |
| 33 | struct dirent *entry; |
| 34 | while ((entry = readdir(dir)) != nullptr) { |
| 35 | if (entry->d_type != DT_DIR) { |
| 36 | continue; |
| 37 | } |
| 38 | std::string pidStr = entry->d_name; |
| 39 | if (!std::all_of(pidStr.begin(), pidStr.end(), ::isdigit)) { |
| 40 | continue; |
| 41 | } |
| 42 | int pid = std::stoi(pidStr); |
| 43 | std::string procExePath = procPath + pidStr + "/exe"; |
| 44 | char exe[256]; |
| 45 | ssize_t len = readlink(procExePath.c_str(), exe, sizeof(exe) - 1); |
| 46 | if (len < 0) { |
| 47 | continue; |
| 48 | } |
| 49 | exe[len] = '\0'; |
| 50 | // get process uid |
| 51 | int uid = -1; |
| 52 | std::string procStatusPath = procPath + pidStr + "/status"; |
| 53 | std::ifstream procStatusFile(procStatusPath); |
| 54 | if (procStatusFile.is_open()) { |
| 55 | std::string line; |
| 56 | while (std::getline(procStatusFile, line)) { |
| 57 | if (line.find("Uid:") == 0) { |
| 58 | std::string uidStr = line.substr(5); |
| 59 | uid = std::stoi(uidStr); |
| 60 | break; |
| 61 | } |
| 62 | } |
| 63 | procStatusFile.close(); |
| 64 | } else { |
| 65 | uid = -1; |
| 66 | } |
| 67 | std::string procCmdlinePath = procPath + pidStr + "/cmdline"; |
| 68 | std::vector<uint8_t> cmdlineBytes; |
| 69 | if (int cmdlineFd = open(procCmdlinePath.c_str(), O_RDONLY); cmdlineFd >= 0) { |
| 70 | std::array<uint8_t, 256> buf = {}; |
| 71 | ssize_t n; |
| 72 | while ((n = read(cmdlineFd, buf.data(), buf.size())) > 0) { |
| 73 | cmdlineBytes.insert(cmdlineBytes.end(), buf.begin(), buf.begin() + n); |
| 74 | } |
| 75 | close(cmdlineFd); |
| 76 | } |
| 77 | ProcessInfo processInfo = {}; |
| 78 | processInfo.pid = pid; |
| 79 | processInfo.uid = uid; |
| 80 | processInfo.exe = exe; |
| 81 | // cmdline is split by '\0', remove the last '\0' if it exists |
| 82 | if (!cmdlineBytes.empty() && cmdlineBytes.back() == '\0') { |