使用popen时必须关闭流

RC1*_*140 3 c popen

正如标题所说,我不确定是否应关闭使用popen打开的流.

我不确定的原因是因为每次我在使用popen打开的流上调用pclose时,我得到一个-1返回代码.

如果我之后打电话给perror,我收到以下消息.

pclose:没有子进程

我在下面使用的代码基本上是运行一个命令并捕获它的输出.我从最后一行得到错误(返回pclose(fileListingStream);)

int executeCommand(char *command) {
    //The Stream to read that will contain the output of the command
    FILE *fileListingStream;
    char path[PATH_MAX];

    //Run the commmand in read mode
    fileListingStream = popen(command,"r");

    //Ensure that its not null before continuing
    if (fileListingStream == NULL)
        return EXIT_FAILURE;

    //Get the data from the stream and then print to the the console
    while (fgets(path, PATH_MAX, fileListingStream) != NULL)
        printf("%s", path);

    //Close the stream and return its return code
    return pclose(fileListingStream);
}
Run Code Online (Sandbox Code Playgroud)

Mat*_*ner 5

是的你应该.请参阅此答案,了解有关内部工作原理的解释pclose().此外,您应该注意到错误wait4()可能是导致明显失败的原因pclose().

Update0

如果FILE *有效(在内部这是由文件描述符表示的-1),pclose() 并且 fclose()如果有错误则不会导致泄漏.值得注意的是,如果FILE *无效,那么无论如何都无需清理.正如我在链接中所讨论的那样,有一些额外的行为pclose(),即FILE *从proc文件链中删除,然后等待子进程终止.内部等待实际上是为a做的第二件事pclose(),此时已经清理了所有内容.在等待之后,立即将其内容FILE删除以表示其无效,无论出现何种错误,都会发生这种情况waitpid().

鉴于您收到的错误ECHILD,我可以明确地说,eglibc-2.11.1pclose()下没有内存泄漏,并且可能至少在过去1 - 4年内任何glibc派生的库.

如果您希望完全确定,只需在valgrind下运行程序,然后触发ECHILD错误.如果有任何泄露,Valgrind会通知您.