我有以下功能
void runSysCall(char *command, char *output)
{
FILE *cmdline = popen(command, "rb");
size_t size = 0;
while(getdelim(&output, &size, 0, cmdline) != -1);
fclose(cmdline);
}
我从这个函数调用它,我返回的是null。
char * getVendorOfTheProcesses()
{
char * result = 0;
runSysCall("cat /proc/cpuinfo | grep -i 'Model'", result);
printf("%s", result);
return "asdsd";
}
如果从函数中打印结果值,它将给出打印输出的内容。
请提供任何帮助。
答案 0 :(得分:1)
请更改您的
FILE *cmdline = popen(command, "rb");
到
FILE *cmdline = popen(command, "r");
它有效(我测试了它 - http://ideone.com/agV18s)。
来自http://pubs.opengroup.org/onlinepubs/009696899/functions/popen.html
popen()的mode参数是一个指定I / O模式的字符串:
如果mode是r,则启动子进程时,其文件描述符 STDOUT_FILENO应该是管道的可写端和文件 调用进程中的描述符fileno(stream),其中stream是 popen()返回的流指针,应该是可读的结尾 管。
如果mode是w,则当子进程启动其文件描述符时 STDIN_FILENO应该是管道的可读端和文件 调用进程中的描述符fileno(stream),其中stream是 popen()返回的流指针,应该是可写的结尾 管。
如果mode是任何其他值,则结果是未定义的。
您似乎使用b
模式导致问题(或获取未定义的行为)。
还要确保free
所有指针以避免内存泄漏。
另请注意,runSysCall
的每次迭代都会覆盖output
。因此,在getVendorOfTheProcesses
打印result
时,您将获得null
,因为这是最后阅读的内容。因此,您必须确保追加每一行并将其返回runSysCall
,而不是使用result
。
我改变了你的代码以合并我的意思 - http://ideone.com/QVTjiD 这只是一个例子,您应该根据自己的需要进行调整,并整合内存管理。
要验证您的代码是否正常运行(在我的机器上计数为128,您可能会有所不同),您可以使用以下内容:
$ cat /proc/cpuinfo | grep -i 'Model' | wc -l
128
$ ./a.out | wc -l
128
希望它有所帮助。
答案 1 :(得分:0)
我认为你没有理解getdelim的工作方式。它的第一个参数是char**
类型,用于返回char *
。因此,您的runSysCall
应该以相同的方式工作: -
void runSysCall(char *command, char **output)
{
....
while(getdelim(output, &size, 0, cmdline) != -1);
...
}
现在,当你调用runSysCall时,第二个参数必须是char**
类型,所以......
char * getVendorOfTheProcesses()
{
char * result = 0;
runSysCall("cat /proc/cpuinfo | grep -i 'Model'", &result);
return result;
}
请注意,从getVendorOfTheProcess
返回的指针由getdelim
在内部进行malloc。为避免泄密,如果在致电free()
后必须getVendorOfTheProcess()
。
您现在应该得到您期望的结果。