几个月前,我编写了一个Linux的CGI应用程序,它使用popen()
来读取命令的输出,然后用fclose()
关闭管道。
现在,我读到关闭管道需要使用pclose()
。
手册说:
popen()
的返回值是所有普通标准I / O流 尊重保存它必须用pclose()
关闭而不是fclose(3)
。
我的代码是这样的:
if ((NULL != (f = popen(command.value, "r")))) {
//do something
fclose(f);
}
我的问题是:
我的错误有安全问题吗?该计划目前正在制作中。在测试中它没有做任何问题。确实需要,使用pclose()
而不是fclose()
对其进行修补?注意:我只在程序中打开一次PIPE。
今天,在我当地的家中,我做了一些测试,fclose()
和pclose()
没有返回EOF表示失败。
答案 0 :(得分:11)
根据this thread,使用fclose
代替pclose
意味着管道另一端的进程无法获取,因此它会保持僵尸状态。
答案 1 :(得分:5)
如果在管道上使用fclose,则会出现文件描述符泄漏,因为fclose不会释放内核中的文件指针(这是在创建管道时创建的,因为它是一个文件)。
虽然到目前为止您的测试没有显示任何问题,但运行您的程序3000次(或者如何允许多个文件描述符,我认为是一个int)并观察何时您将无法再创建管道。
答案 2 :(得分:0)
我刚刚发现(10年后)我错误地使用fclose
进行了一些popen
调用,在Windows 2008服务器上运行。它工作(即没有崩溃),我不关心这些调用的返回代码。
但我需要上一个popen
流的返回代码,并且已使用pclose
正确完成关闭。
它具有返回0错误代码(可能收集以前不是pclosed
进程的返回代码)的奇怪效果,即使命令失败,也会在代码中创建一个非常奇怪的错误,这可能导致因为调用者认为该命令有效,所以会发生灾难性错误。
因此,这不仅仅是泄漏描述符的问题,它可能会在代码中引入功能性错误(即使应用程序运行了几秒钟而且您不关心泄漏描述符)