| 97 | } |
| 98 | |
| 99 | bool getProcessInfo(int pid, ProcessInfo &info) { |
| 100 | std::string procPath = "/proc/"; |
| 101 | std::string pidStr = std::to_string(pid); |
| 102 | // get process uid |
| 103 | int uid = -1; |
| 104 | std::string procStatusPath = procPath + pidStr + "/status"; |
| 105 | std::ifstream procStatusFile(procStatusPath); |
| 106 | if (procStatusFile.is_open()) { |
| 107 | std::string line; |
| 108 | while (std::getline(procStatusFile, line)) { |
| 109 | if (line.find("Uid:") == 0) { |
| 110 | std::string uidStr = line.substr(5); |
| 111 | uid = std::stoi(uidStr); |
| 112 | break; |
| 113 | } |
| 114 | } |
| 115 | procStatusFile.close(); |
| 116 | } else { |
| 117 | return false; |
| 118 | } |
| 119 | std::string procCmdlinePath = procPath + pidStr + "/cmdline"; |
| 120 | std::vector<uint8_t> cmdlineBytes; |
| 121 | if (int cmdlineFd = open(procCmdlinePath.c_str(), O_RDONLY); cmdlineFd >= 0) { |
| 122 | std::array<uint8_t, 256> buf = {}; |
| 123 | ssize_t n; |
| 124 | while ((n = read(cmdlineFd, buf.data(), buf.size())) > 0) { |
| 125 | cmdlineBytes.insert(cmdlineBytes.end(), buf.begin(), buf.begin() + n); |
| 126 | } |
| 127 | close(cmdlineFd); |
| 128 | } |
| 129 | // cmdline is split by '\0', remove the last '\0' if it exists |
| 130 | if (!cmdlineBytes.empty() && cmdlineBytes.back() == '\0') { |
| 131 | cmdlineBytes.pop_back(); |
| 132 | } |
| 133 | if (!cmdlineBytes.empty()) { |
| 134 | info.cmdline = utils::splitString(std::string( |
| 135 | reinterpret_cast<const char *>(cmdlineBytes.data()), cmdlineBytes.size()), std::string("\0", 1)); |
| 136 | info.argv0 = info.cmdline.front(); |
| 137 | } |
| 138 | info.pid = pid; |
| 139 | info.uid = uid; |
| 140 | // get process exe path |
| 141 | std::string procExePath = procPath + pidStr + "/exe"; |
| 142 | char exe[256]; |
| 143 | ssize_t len = readlink(procExePath.c_str(), exe, sizeof(exe) - 1); |
| 144 | if (len < 0) { |
| 145 | return false; |
| 146 | } |
| 147 | exe[len] = '\0'; |
| 148 | info.exe = exe; |
| 149 | if (!info.exe.empty()) { |
| 150 | info.name = info.exe.substr(info.exe.find_last_of('/') + 1); |
| 151 | } |
| 152 | return true; |
| 153 | } |
| 154 | |
| 155 | int getKernelArchitecture() noexcept { |
| 156 | struct utsname uts = {}; |