7

几个月前,我为 Linux 编写了一个 CGI 应用程序,用于popen()读取命令的输出,然后我用fclose().

现在,我读到对于封闭管道是需要使用pclose().

手册说:

from 的返回值popen()在所有方面都是正常的标准 I/O 流,除了它必须用pclose()而不是 . 关闭fclose(3)

我的代码是这样的:

if ((NULL != (f = popen(command.value, "r")))) {
    //do something
    fclose(f);
}

我的问题是:

我的错误有安全问题吗?它程序目前正在生产中。在测试中它没有做任何问题。真的需要,pclose()改用补丁fclose()吗?注意:我只在程序中打开 PIPE 一次。

今天,在我当地的家中,我做了一些测试fclose()并且pclose()没有返回 EOF 指示失败。

4

3 回答 3

11

根据这个线程,使用fclose而不是pclose意味着管道另一端的进程不会被收割,所以它保持僵尸状态。

于 2013-08-19T16:15:41.837 回答
6

如果您在管道上使用 fclose,您将有文件描述符泄漏,因为 fclose 不会释放内核中的文件指针(它是在您创建管道时创建的,因为它是一个文件)。

虽然到目前为止您的测试没有显示任何问题,但运行您的程序 3000 次(或者允许多少文件描述符,我认为超过一个 int)并观察您何时不再能够创建管道。

于 2013-08-19T16:15:32.027 回答
0

我刚刚发现(10 年后)我错误地使用fclose了一些popen调用,在 Windows 2008 服务器上运行。它起作用了(即没有崩溃),无论如何我都不关心这些调用的返回码。

但是我需要最后一个popen流的返回码,并且关闭是用pclose.

它具有返回 0 错误代码的奇怪效果(可能收集了以前未处理的返回代码pclosed),即使命令失败,也会在代码中创建一个非常奇怪的错误,这可能导致灾难性错误,因为调用者认为该命令有效。

因此,这不仅仅是泄漏描述符的问题,它可能会在您的代码中引入功能错误(即使应用程序运行了几秒钟并且您不关心泄漏描述符)

于 2017-10-27T19:09:32.030 回答