|
13 | 13 | #include "lldb/Utility/ProcessInfo.h"
|
14 | 14 | #include "lldb/Utility/Status.h"
|
15 | 15 | #include "llvm/BinaryFormat/XCOFF.h"
|
| 16 | +#include <dirent.h> |
16 | 17 | #include <sys/proc.h>
|
17 | 18 | #include <sys/procfs.h>
|
18 | 19 |
|
@@ -41,6 +42,14 @@ static ProcessInstanceInfo::timespec convert(pr_timestruc64_t t) {
|
41 | 42 | return ts;
|
42 | 43 | }
|
43 | 44 |
|
| 45 | +static bool IsDirNumeric(const char *dname) { |
| 46 | + for (; *dname; dname++) { |
| 47 | + if (!isdigit(*dname)) |
| 48 | + return false; |
| 49 | + } |
| 50 | + return true; |
| 51 | +} |
| 52 | + |
44 | 53 | static bool GetStatusInfo(::pid_t pid, ProcessInstanceInfo &processInfo,
|
45 | 54 | ProcessState &State) {
|
46 | 55 | struct pstatus pstatusData;
|
@@ -133,7 +142,45 @@ static bool GetProcessAndStatInfo(::pid_t pid,
|
133 | 142 |
|
134 | 143 | uint32_t Host::FindProcessesImpl(const ProcessInstanceInfoMatch &match_info,
|
135 | 144 | ProcessInstanceInfoList &process_infos) {
|
136 |
| - return 0; |
| 145 | + static const char procdir[] = "/proc/"; |
| 146 | + |
| 147 | + DIR *dirproc = opendir(procdir); |
| 148 | + if (dirproc) { |
| 149 | + struct dirent *direntry = nullptr; |
| 150 | + const uid_t our_uid = getuid(); |
| 151 | + const lldb::pid_t our_pid = getpid(); |
| 152 | + bool all_users = match_info.GetMatchAllUsers(); |
| 153 | + |
| 154 | + while ((direntry = readdir(dirproc)) != nullptr) { |
| 155 | + if (!IsDirNumeric(direntry->d_name)) |
| 156 | + continue; |
| 157 | + |
| 158 | + lldb::pid_t pid = atoi(direntry->d_name); |
| 159 | + // Skip this process. |
| 160 | + if (pid == our_pid) |
| 161 | + continue; |
| 162 | + |
| 163 | + ProcessState State; |
| 164 | + ProcessInstanceInfo process_info; |
| 165 | + if (!GetProcessAndStatInfo(pid, process_info, State)) |
| 166 | + continue; |
| 167 | + |
| 168 | + if (State == ProcessState::Zombie || |
| 169 | + State == ProcessState::TracedOrStopped) |
| 170 | + continue; |
| 171 | + |
| 172 | + // Check for user match if we're not matching all users and not running |
| 173 | + // as root. |
| 174 | + if (!all_users && (our_uid != 0) && (process_info.GetUserID() != our_uid)) |
| 175 | + continue; |
| 176 | + |
| 177 | + if (match_info.Matches(process_info)) { |
| 178 | + process_infos.push_back(process_info); |
| 179 | + } |
| 180 | + } |
| 181 | + closedir(dirproc); |
| 182 | + } |
| 183 | + return process_infos.size(); |
137 | 184 | }
|
138 | 185 |
|
139 | 186 | bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) {
|
|
0 commit comments