1

我有以下功能

void runSysCall(char *command, char *output)
{

    FILE *cmdline = popen(command, "rb");
    size_t size = 0;


    while(getdelim(&output, &size, 0, cmdline) != -1);

    fclose(cmdline);
}

我从这个函数调用它,而我返回的是空值。

char * getVendorOfTheProcesses()
{

    char * result = 0;
    runSysCall("cat /proc/cpuinfo | grep -i 'Model'", result);

    printf("%s", result);
    return "asdsd";
}

如果您从函数打印结果值,它将给出它应该打印的内容。

请任何帮助将不胜感激。

4

2 回答 2

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您 print 时result,您将得到null,因为这是最后阅读的内容。因此,您必须确保附加每一行并将其返回到runSysCall而不是使用result.

我稍微更改了您的代码以合并我的意思- http://ideone.com/QVTjiD 这只是一个示例,您应该根据自己的需要对其进行调整并合并内存管理。

要验证您的代码是否正常工作(在我的机器上计数为 128,您可能会有所不同),您可以使用如下内容:

$ cat /proc/cpuinfo | grep -i 'Model' | wc -l
128
$ ./a.out | wc -l
128

希望能帮助到你。

于 2013-05-14T20:54:45.980 回答
0

我认为您还没有掌握getdelim 的工作原理。它的第一个参数是 type char**,它用来返回一个char *. 所以,你runSysCall应该以同样的方式工作: -

void runSysCall(char *command, char **output)
{
  ....
  while(getdelim(output, &size, 0, cmdline) != -1);
  ...
}

现在,当您调用 runSysCall 时,第二个参数必须是 type char**,所以...

char * getVendorOfTheProcesses()
{
  char * result = 0;
  runSysCall("cat /proc/cpuinfo | grep -i 'Model'", &result);

  return result;
}

请注意,从getVendorOfTheProcess内部返回的指针是由getdelim. 为避免泄漏,您必须free()在调用getVendorOfTheProcess().

您现在应该得到您期望的结果。

于 2013-05-14T21:04:13.467 回答