OSX:proc_pidinfo为其他用户的进程返回0 [英] OSX: proc_pidinfo returns 0 for other user's processes

查看:82
本文介绍了OSX:proc_pidinfo为其他用户的进程返回0的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要获取有关在Mac OSX上运行的进程的一些信息(PID,UID,GID,进程名称).我尝试了 proc_pidinfo .对于我自己的流程,它可以正常工作.但是,对于其他用户拥有的进程,将返回0.没有此功能的文档,但是根据在Internet上找到的信息,它是应该返回写入提供的缓冲区的字节数.在其他用户的进程上调用此函数将返回0,这意味着未提供任何信息.

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.

示例:

#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 的行为是一致的:

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

但是,活动监视器没有SUID即可工作.

But then, Activity Monitor works without SUID.

所以,我的问题是,为什么 proc_pidinfo 仅提供有关我自己的进程的信息?我可以使其提供有关其他过程的信息吗?如果没有,如何在不解析 ps(1)输出的情况下获得此信息?

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?

推荐答案

我发现macOS Mojave(版本10.14.4)具有 struct proc_bsdshortinfo ,它是 struct proc_bsdinfo .您可以使用SUID代替 struct proc_bsdinfo 来获得没有SUID的其他用户的进程.

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.

已编辑:至少从macOS 10.10.5(Yosemite)起可用.
再次编辑:自Mac OS X 10.7(Lion)以来,该功能可能可用,因为如果定义了 __ MAC_10_7 ,则tmux使用 struct proc_bsdshortinfo .请参见此处.

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.

示例:

#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;
}

该程序打印:

$ ./pidinfo 
 pid: 3025
ppid: 250
comm: pidinfo
 uid: 501
 gid: 20
$ ./pidinfo 1
 pid: 1
ppid: 0
comm: launchd
 uid: 0
 gid: 0

这篇关于OSX:proc_pidinfo为其他用户的进程返回0的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆