I need to get some information (PID, UID, GID, process name) about running processes on Mac OSX. I tried proc_pidinfo
. For my own processes it works fine. However, for processes owned by other users, 0 is returned. There's no documentation for this function, but according to information found on Internet, it's supposed to return number of bytes written into provided buffer. Calling this function on other user's processes returns 0, which means that no information was provided.
Example:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <libproc.h>
int main(int argc, char *argv[])
{
pid_t pid;
struct proc_bsdinfo proc;
if (argc == 2)
pid = atoi(argv[1]);
else
pid = getpid();
int st = proc_pidinfo(pid, PROC_PIDTBSDINFO, 0,
&proc, PROC_PIDTBSDINFO_SIZE);
if (st != PROC_PIDTBSDINFO_SIZE) {
fprintf(stderr, "Cannot get process info");
return 1;
}
printf(" pid: %d\n", (int)proc.pbi_pid);
printf("ppid: %d\n", (int)proc.pbi_ppid);
printf("comm: %s\n", proc.pbi_comm);
printf("name: %s\n", proc.pbi_name);
printf(" uid: %d\n", (int)proc.pbi_uid);
printf(" gid: %d\n", (int)proc.pbi_gid);
return 0;
}
Running this program yields:
$ ./pidinfo
pid: 30519
ppid: 8434
comm: pidinfo
name: pidinfo
uid: 501
gid: 20
$ ./pidinfo 1
Cannot get process info
$ sudo ./pidinfo 1
pid: 1
ppid: 0
comm: launchd
name: launchd
uid: 0
gid: 0
That's strange, because I can get all this information from ps(1)
. But then I checked that both ps
and top
on OSX are SUID binaries, which would be in line with proc_pidinfo
behavior:
$ ls -l `which ps` `which top`
-rwsr-xr-x 1 root wheel 51008 5 maj 08:06 /bin/ps
-r-sr-xr-x 1 root wheel 87952 5 maj 08:05 /usr/bin/top
But then, Activity Monitor works without SUID.
So, my question is, why proc_pidinfo
provides information only about my own processes? Can I make it give me information about other processes? If not, how can I get this information without parsing ps(1)
output?
You can use :
int proc_listpids(uint32_t type, uint32_t typeinfo, void *buffer, int buffersize);
combinated to proc_pidinfo to get many others pids informations like :
#include <unistd.h>
#include <stdlib.h>
#include <mach/mach.h>
#include <libproc.h>
#include <mach/mach_time.h>
#include <sys/sysctl.h>
#include <mach-o/ldsyms.h>
#include <stdio.h>
void procpid(pid_t pid)
{ struct proc_bsdinfo proc;
int st = proc_pidinfo(pid, PROC_PIDTBSDINFO, 0, &proc, PROC_PIDTBSDINFO_SIZE);
printf("name: %s\n", proc.pbi_name);
}
void pidlist(void)
{ int bufsize = proc_listpids(PROC_ALL_PIDS, 0, NULL, 0);
pid_t pids[2 * bufsize / sizeof(pid_t)];
bufsize = proc_listpids(PROC_ALL_PIDS, 0, pids, sizeof(pids));
size_t num_pids = bufsize / sizeof(pid_t);
int i = 0;
while (i < num_pids)
{ printf("pid[%d]::%d\n", i, pids[i]);
procpid(pids[i]);
printf("\n-------------------------------\n\n");
i += 1; }}
int main(void)
{ pidlist();
return(42); }
I found that macOS Mojave (version 10.14.4) had struct proc_bsdshortinfo
, which is a subset of struct proc_bsdinfo
. You can get other user's processes without SUID by using it instead of struct proc_bsdinfo
.
Well, I don't know from which version it is available.
edited: It is available since at least macOS 10.10.5 (Yosemite).
edited again: It may be available since Mac OS X 10.7 (Lion) because tmux uses struct proc_bsdshortinfo
if __MAC_10_7
is defined. See here.
Example:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <libproc.h>
int main(int argc, char *argv[])
{
pid_t pid;
struct proc_bsdshortinfo proc;
if (argc == 2)
pid = atoi(argv[1]);
else
pid = getpid();
int st = proc_pidinfo(pid, PROC_PIDT_SHORTBSDINFO, 0,
&proc, PROC_PIDT_SHORTBSDINFO_SIZE);
if (st != PROC_PIDT_SHORTBSDINFO_SIZE) {
fprintf(stderr, "Cannot get process info\n");
return 1;
}
printf(" pid: %d\n", (int)proc.pbsi_pid);
printf("ppid: %d\n", (int)proc.pbsi_ppid);
printf("comm: %s\n", proc.pbsi_comm);
//printf("name: %s\n", proc.pbsi_name);
printf(" uid: %d\n", (int)proc.pbsi_uid);
printf(" gid: %d\n", (int)proc.pbsi_gid);
return 0;
}
This program prints:
$ ./pidinfo
pid: 3025
ppid: 250
comm: pidinfo
uid: 501
gid: 20
$ ./pidinfo 1
pid: 1
ppid: 0
comm: launchd
uid: 0
gid: 0
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With