How to programmatically get uid from pid in osx using C ++?

Given pid, I want to find the owner of the process (like uid). Is there a way to get this in osx (or any unix) using C ++?

Google did not help. "ps" is able to do this; so I guess there should be a way to get it programmatically.

+3
source share
5 answers

Finally found a way to programmatically do this without parsing the output of 'ps'

uint getUidUsingSysctl(uint pid) { struct kinfo_proc *sProcesses = NULL, *sNewProcesses; int aiNames[4]; size_t iNamesLength; int i, iRetCode, iNumProcs; size_t iSize; iSize = 0; aiNames[0] = CTL_KERN; aiNames[1] = KERN_PROC; aiNames[2] = KERN_PROC_ALL; aiNames[3] = 0; iNamesLength = 3; iRetCode = sysctl(aiNames, iNamesLength, NULL, &iSize, NULL, 0); /* allocate memory and populate info in the processes structure */ do { iSize += iSize / 10; sNewProcesses = (kinfo_proc *)realloc(sProcesses, iSize); if (sNewProcesses == 0) { if (sProcesses) free(sProcesses); /* could not realloc memory, just return */ return -1; } sProcesses = sNewProcesses; iRetCode = sysctl(aiNames, iNamesLength, sProcesses, &iSize, NULL, 0); } while (iRetCode == -1 && errno == ENOMEM); iNumProcs = iSize / sizeof(struct kinfo_proc); for (i = 0; i < iNumProcs; i++) { if (sProcesses[i].kp_proc.p_pid == pid) { return sProcesses[i].kp_eproc.e_ucred.cr_uid; } } /* clean up and return to the caller */ free(sProcesses); return -1; } 

Note. Perhaps the best way to get "kinfo_proc" instead of repeating the whole process.

+1
source

The source for the ps command shows that there is a get_proc_stats function defined in proc / readproc.h that (among other things) returns a real user name(UID) and an Effective user name(EUID) for a given pid.

You need to install libproc-dev to get this function. and then you can:

 #include <proc/readproc.h> void printppid(pid_t pid) { proc_t process_info; get_proc_stats(pid, &process_info); printf("Real user of the process[%d] is [%s]\n", pid, process_info.ruser); } 

compile it with gcc the-file.c -lproc .

Once you have a real username, you can use getpwnam () and getgrnam () to get the uid.

+4
source

You can see how ps does it . It looks like it is using the kvm_getprocs function.

However, it is much more portable (you said "any unix", but, for example, Linux and Solaris, look at the /proc file system, and other unixes can have different APIs) to just parse the ps output ( ps -o user= -p (pid) for example, to exclude any extraneous output) than to do any system processes

+3
source

A solution from Indhu helped me on my way, so I would like to publish my own.

UID of PID with pure C:

 #include <sys/sysctl.h> uid_t uidFromPid(pid_t pid) { uid_t uid = -1; struct kinfo_proc process; size_t procBufferSize = sizeof(process); // Compose search path for sysctl. Here you can specify PID directly. const u_int pathLenth = 4; int path[pathLenth] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid}; int sysctlResult = sysctl(path, pathLenth, &process, &procBufferSize, NULL, 0); // If sysctl did not fail and process with PID available - take UID. if ((sysctlResult == 0) && (procBufferSize != 0)) { uid = process.kp_eproc.e_ucred.cr_uid; } return uid; } 

Lack of excessive allocation, lack of cycles.

+3
source

There is no portable way to do this. On Mac OS, you need to use the low-documented sysctl interfaces: see this previous stack question). (As other commentators noted, on Linux you can use proc. On FreeBSD, you can use kvm_getfiles , although this is not available on Mac OS.)

It is best to use the source for Apple ps as a transition point for capturing process data, you can use getpwuid(3) after you have the uid.

+2
source

Source: https://habr.com/ru/post/1243011/


All Articles