【发布时间】:2020-12-29 08:50:40
【问题描述】:
我需要获取有关在 Mac OSX 上运行的进程的一些信息(PID、UID、GID、进程名称)。我试过proc_pidinfo。对于我自己的流程,它工作正常。但是,对于其他用户拥有的进程,返回 0。这个函数没有文档,但根据information found on Internet,它应该返回写入提供的缓冲区的字节数。在其他用户的进程上调用该函数返回0,表示没有提供任何信息。
例子:
#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;
}
运行这个程序产生:
$ ./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
这很奇怪,因为我可以从ps(1) 获得所有这些信息。但后来我检查了 OSX 上的 ps 和 top 都是 SUID 二进制文件,这符合 proc_pidinfo 的行为:
$ 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
但是,Activity Monitor 可以在没有 SUID 的情况下工作。
那么,我的问题是,为什么proc_pidinfo 只提供关于我自己的流程的信息?我可以让它给我有关其他流程的信息吗?如果没有,如何在不解析ps(1) 输出的情况下获取此信息?
【问题讨论】:
-
过去,Activity Monitor 确实使用了 SUID 工具,不过现在已经改为使用以
root运行的启动守护进程:/usr/libexec/sysmond,也可能还有/usr/libexec/systemstatsd... -
我认为如果你以 root 权限运行
proc_pidinfo,你将能够获取所有进程的信息。 -
如果我使用
sudo运行我的程序,它可以工作 - 请参阅我的示例。但我不想以 root 身份运行我的程序。