C 关闭标准管道和标准管道

C 关闭标准管道和标准管道,c,stdout,stdin,file-descriptor,C,Stdout,Stdin,File Descriptor,我被ptunnel关闭stdin、stdout和stderr的方式吸引住了: if (daemonize) { ... freopen("/dev/null", "r", stdin); freopen("/dev/null", "w", stdout); freopen("/dev/null", "w", stderr); } 这是关闭它们的好方法吗?我很困惑,因为freopen将打开一个文件描述符,而在这种情况下它不会关闭。否。它不是完全安全的 它假设fre

我被
ptunnel
关闭stdin、stdout和stderr的方式吸引住了:

if (daemonize)
{
    ...
    freopen("/dev/null", "r", stdin);
    freopen("/dev/null", "w", stdout);
    freopen("/dev/null", "w", stderr);
}

这是关闭它们的好方法吗?我很困惑,因为freopen将打开一个文件描述符,而在这种情况下它不会关闭。

否。它不是完全安全的

它假设freopen()重用了相同的文件描述符,但这并不能保证。因此,如果freopen()使用不同的文件描述符,例如,对于
stdout
,而不是
1
,那么后续的
write()
使用该文件描述符将无法正常工作。因为POSIX读/写函数使用
*\u FILENO
定义为:

/* Standard file descriptors.  */
#define STDIN_FILENO    0       /* Standard input.  */
#define STDOUT_FILENO   1       /* Standard output.  */
#define STDERR_FILENO   2       /* Standard error output.  */
用于各自的IO操作

相反,你可以做:

#include<unistd.h>

  fd = open("/dev/null",O_RDWR);
  dup2(fd,0);
  dup2(fd,1);
  dup2(fd,2); 
#包括
fd=打开(“/dev/null”,O_RDWR);
dup2(fd,0);
dup2(fd,1);
dup2(fd,2);
实现同样的目标。明显的缺点是
open()
dup2()
是POSIX函数,不属于C标准

但只要
freopen()
分别重用文件描述符0、1和2,或者不使用可能不正确的文件描述符执行任何IO,您就安全了