2010-04-02 70 views
0

下面是一个削减(错误/ null检查省略)的C /的OBJ-C代码段,它使用的sysctl得到一个特定过程的用的argv PID 50.为什么sysctl在Mac OS X上生成E_INVAL?

... 
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,但无法看到我的问题。我错过了什么?

回答

2

我试过了包装你的代码到一个程序,并能正常工作,并打印出的其他进程的argv的等询问我自己的流程,即约一,一个具有相同uid的过程调用sysctl()

“比我预期的大”方面是因为进程的环境变量以及命令行参数。 (这不是什么明显的所有这些信息的格式。)

当询问一个不同用户的过程中,我从你已经看到第二sysctl得到相同EINVAL。我想这被认为是对其他人的过程的无理的好奇心,但你会认为第一个sysctl也会失败。

(当询问一个不存在的PID,第一sysctl失败EINVAL。)

这一切都似乎是大量未公开:在Leopard,KERN_PROCARGS甚至没有出现在sysctl手册页。

+0

就是这样;当我尝试使用自己的PID时,它可以工作。我也在http://www.opensource.apple.com/source/xnu/xnu-792.12.6/bsd/kern/kern_sysctl.c(请参阅sysctl_procargsx)中做了一些挖掘,并且它确实在实际得到参数的情况下,但不是当你刚刚得到的长度。现在我只是想知道'ps'如何能够获得所有进程的参数,但我想这是一个单独的问题。 – DNS 2010-04-02 20:02:34

+0

'ps'的常用方法是setuid root,因此可以任意使用KERN_PROCARGS或其他超级大国。那个sysctl_procargsx()源代码是有趣的,它只是返回用户堆栈的基础 - 返回main(argc,argv,envp)堆栈框架明确了为什么环境变量也会返回,并且说... er ...关于返回数据的格式。 – 2010-04-02 20:17:09