以下是使用sysctl来获取PID为50的特定进程的argv的C / Obj-C代码的简短摘要(省略了错误/空值检查)。
...
int getProcessArgs[3] = { CTL_KERN, KERN_PROCARGS, 50 };
sysctl(getProcessArgs, 3, NULL, &length, NULL, 0);
char* processArgs = malloc(length * sizeof(char));
sysctl(getProcessArgs, 3, processArgs, &length, NULL, 0);
...
对sysctl的第一次调用(确定argv字符串数组的大小)成功。返回的长度是〜1600,比我期望的要大,但是我想这并不合理。 Malloc成功。对sysctl的第二次调用返回-1,将errno设置为22,E_INVAL。
我查看了其他代码,包括来自this question的代码,但看不到我的问题。我想念什么?
最佳答案
我尝试将您的代码包装到一个程序中,当查询我自己的进程之一(即与调用sysctl()
的进程具有相同uid的进程)时,它可以正常工作并打印出另一个进程的argv等。
“比我预期的要大”的方面是因为返回了进程的环境变量以及命令行参数。 (尚不清楚所有这些信息的格式是什么。)
当询问其他用户的进程时,我从您看到的第二个sysctl
中得到了相同的EINVAL。我认为这被认为对其他人的流程不合理,但您会认为第一个sysctl
也会失败。
(查询不存在的pid时,第一个sysctl
失败,并显示EINVAL。)
这一切似乎都未得到充分记录:在Leopard上,KERN_PROCARGS
甚至没有出现在sysctl
手册页中。