从进程ID获取进程名称?

8

我正在使用OSX Mountain Lion操作系统,尝试通过进程ID获取进程名称。

以下是我正在使用的代码:

pid_t pid = 10687;
char pathBuffer [PROC_PIDPATHINFO_MAXSIZE] = "";
char nameBuffer [256] = "";

int sizeOfVal = sizeof(nameBuffer);
proc_pidpath(pid, pathBuffer, sizeof(pathBuffer));
proc_name(pid, nameBuffer, sizeof(nameBuffer));

NSLog(@"Path: %s\n Name: %s\n", pathBuffer, nameBuffer);

以上代码能够正确地检索到名称,但只能检索前15个字符并“忽略”其余部分。请注意,这不是显示名称的问题,而是“检索”它的问题。我的应用程序的其他部分没有问题,因为我正在独立的应用程序中测试上述代码。还要注意,我尝试更改PID,但无论我尝试什么PID,此代码仅检索名称的前15个字符。路径检索完美运行。
有人对我做错了什么有什么想法吗?

在我调查这个问题时,我发现了一些更奇怪的事情。如果指定的缓冲区长度小于32字节,则即使名称很短(并且可以适合31字节的缓冲区),也不会放入字符串中任何内容。 - charliehorse55
1个回答

11

这个函数查看的是结构体proc_bsdshortinfo中的值。它仅限于返回一个16字节的字符串,或者包括空终止符在内的15个可读字符。

来自 sys/param.h:

#define MAXCOMLEN   16      /* max command name remembered */

来自sys/proc_info.h

struct proc_bsdshortinfo {
        uint32_t                pbsi_pid;       /* process id */
        uint32_t                pbsi_ppid;      /* process parent id */
        uint32_t                pbsi_pgid;      /* process perp id */
    uint32_t                pbsi_status;        /* p_stat value, SZOMB, SRUN, etc */
    char                    pbsi_comm[MAXCOMLEN];   /* upto 16 characters of process name */
    uint32_t                pbsi_flags;              /* 64bit; emulated etc */
        uid_t                   pbsi_uid;       /* current uid on process */
        gid_t                   pbsi_gid;       /* current gid on process */
        uid_t                   pbsi_ruid;      /* current ruid on process */
        gid_t                   pbsi_rgid;      /* current tgid on process */
        uid_t                   pbsi_svuid;     /* current svuid on process */
        gid_t                   pbsi_svgid;     /* current svgid on process */
        uint32_t                pbsi_rfu;       /* reserved for future use*/
};

编辑:为了绕过这个问题,获取最后一个路径组件:

pid_t pid = 3051;
char pathBuffer [PROC_PIDPATHINFO_MAXSIZE];
proc_pidpath(pid, pathBuffer, sizeof(pathBuffer));

char nameBuffer[256];

int position = strlen(pathBuffer);
while(position >= 0 && pathBuffer[position] != '/')
{
    position--;
}

strcpy(nameBuffer, pathBuffer + position + 1);

printf("path: %s\n\nname:%s\n\n", pathBuffer, nameBuffer);

获取完整路径,然后将字符串修剪到最后一个路径组件。 - charliehorse55
难道没有更优雅的解决方案吗?考虑到检索进程信息是许多程序的重要部分,应该有一种更高效的接口来检索这些信息。 - fdh
虽然检索进程信息很重要,但大多数应用程序甚至不关心名称是什么。 - charliehorse55
2
如果您查看诸如 ps 这样的程序源代码,这就是它们获取长名称的方式。 - charliehorse55
@charliehorse55,如何获取启动进程时的命令参数? - user429620

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接