static bool GetFreeBSDProcessUserAndGroup(ProcessInstanceInfo &process_info) { struct kinfo_proc proc_kinfo; size_t proc_kinfo_size; if (process_info.ProcessIDIsValid()) { int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, (int)process_info.GetProcessID() }; proc_kinfo_size = sizeof(struct kinfo_proc); if (::sysctl (mib, 4, &proc_kinfo, &proc_kinfo_size, NULL, 0) == 0) { if (proc_kinfo_size > 0) { process_info.SetParentProcessID (proc_kinfo.ki_ppid); process_info.SetUserID (proc_kinfo.ki_ruid); process_info.SetGroupID (proc_kinfo.ki_rgid); process_info.SetEffectiveUserID (proc_kinfo.ki_uid); if (proc_kinfo.ki_ngroups > 0) process_info.SetEffectiveGroupID (proc_kinfo.ki_groups[0]); else process_info.SetEffectiveGroupID (UINT32_MAX); return true; } } } process_info.SetParentProcessID (LLDB_INVALID_PROCESS_ID); process_info.SetUserID (UINT32_MAX); process_info.SetGroupID (UINT32_MAX); process_info.SetEffectiveUserID (UINT32_MAX); process_info.SetEffectiveGroupID (UINT32_MAX); return false; }
static bool GetNetBSDProcessUserAndGroup(ProcessInstanceInfo &process_info) { ::kvm_t *kdp; char errbuf[_POSIX2_LINE_MAX]; /* XXX: error string unused */ struct ::kinfo_proc2 *proc_kinfo; const int pid = process_info.GetProcessID(); int nproc; if (!process_info.ProcessIDIsValid()) goto error; if ((kdp = ::kvm_openfiles(NULL, NULL, NULL, KVM_NO_FILES, errbuf)) == NULL) goto error; if ((proc_kinfo = ::kvm_getproc2(kdp, KERN_PROC_PID, pid, sizeof(struct ::kinfo_proc2), &nproc)) == NULL) { ::kvm_close(kdp); goto error; } if (nproc < 1) { ::kvm_close(kdp); /* XXX: we don't check for error here */ goto error; } process_info.SetParentProcessID (proc_kinfo->p_ppid); process_info.SetUserID (proc_kinfo->p_ruid); process_info.SetGroupID (proc_kinfo->p_rgid); process_info.SetEffectiveUserID (proc_kinfo->p_uid); process_info.SetEffectiveGroupID (proc_kinfo->p_gid); ::kvm_close(kdp); /* XXX: we don't check for error here */ return true; error: process_info.SetParentProcessID (LLDB_INVALID_PROCESS_ID); process_info.SetUserID (UINT32_MAX); process_info.SetGroupID (UINT32_MAX); process_info.SetEffectiveUserID (UINT32_MAX); process_info.SetEffectiveGroupID (UINT32_MAX); return false; }
static void GetLinuxProcessUserAndGroup (lldb::pid_t pid, ProcessInstanceInfo &process_info, lldb::pid_t &tracerpid) { tracerpid = 0; uint32_t rUid = UINT32_MAX; // Real User ID uint32_t eUid = UINT32_MAX; // Effective User ID uint32_t rGid = UINT32_MAX; // Real Group ID uint32_t eGid = UINT32_MAX; // Effective Group ID // Read the /proc/$PID/status file and parse the Uid:, Gid:, and TracerPid: fields. lldb::DataBufferSP buf_sp = ReadProcPseudoFile (pid, "status"); static const char uid_token[] = "Uid:"; char *buf_uid = strstr ((char *)buf_sp->GetBytes(), uid_token); if (buf_uid) { // Real, effective, saved set, and file system UIDs. Read the first two. buf_uid += sizeof(uid_token); rUid = strtol (buf_uid, &buf_uid, 10); eUid = strtol (buf_uid, &buf_uid, 10); } static const char gid_token[] = "Gid:"; char *buf_gid = strstr ((char *)buf_sp->GetBytes(), gid_token); if (buf_gid) { // Real, effective, saved set, and file system GIDs. Read the first two. buf_gid += sizeof(gid_token); rGid = strtol (buf_gid, &buf_gid, 10); eGid = strtol (buf_gid, &buf_gid, 10); } static const char tracerpid_token[] = "TracerPid:"; char *buf_tracerpid = strstr((char *)buf_sp->GetBytes(), tracerpid_token); if (buf_tracerpid) { // Tracer PID. 0 if we're not being debugged. buf_tracerpid += sizeof(tracerpid_token); tracerpid = strtol (buf_tracerpid, &buf_tracerpid, 10); } process_info.SetUserID (rUid); process_info.SetEffectiveUserID (eUid); process_info.SetGroupID (rGid); process_info.SetEffectiveGroupID (eGid); }
static bool GetStatusInfo(::pid_t Pid, ProcessInstanceInfo &ProcessInfo, ProcessState &State, ::pid_t &TracerPid) { auto BufferOrError = getProcFile(Pid, "status"); if (!BufferOrError) return false; llvm::StringRef Rest = BufferOrError.get()->getBuffer(); while(!Rest.empty()) { llvm::StringRef Line; std::tie(Line, Rest) = Rest.split('\n'); if (Line.consume_front("Gid:")) { // Real, effective, saved set, and file system GIDs. Read the first two. Line = Line.ltrim(); uint32_t RGid, EGid; Line.consumeInteger(10, RGid); Line = Line.ltrim(); Line.consumeInteger(10, EGid); ProcessInfo.SetGroupID(RGid); ProcessInfo.SetEffectiveGroupID(EGid); } else if (Line.consume_front("Uid:")) { // Real, effective, saved set, and file system UIDs. Read the first two. Line = Line.ltrim(); uint32_t RUid, EUid; Line.consumeInteger(10, RUid); Line = Line.ltrim(); Line.consumeInteger(10, EUid); ProcessInfo.SetUserID(RUid); ProcessInfo.SetEffectiveUserID(EUid); } else if (Line.consume_front("PPid:")) { ::pid_t PPid; Line.ltrim().consumeInteger(10, PPid); ProcessInfo.SetParentProcessID(PPid); } else if (Line.consume_front("State:")) { char S = Line.ltrim().front(); switch (S) { case 'R': State = ProcessState::Running; break; case 'S': State = ProcessState::Sleeping; break; case 'D': State = ProcessState::DiskSleep; break; case 'Z': State = ProcessState::Zombie; break; case 'T': State = ProcessState::TracedOrStopped; break; case 'W': State = ProcessState::Paging; break; } } else if (Line.consume_front("TracerPid:")) { Line = Line.ltrim(); Line.consumeInteger(10, TracerPid); } } return true; }