如何判断一个流是否在调用fclose之前在C中关闭()

问题描述:

我有一个失败的C程序,并且我已经缩小到一个fork() ed孩子试图关闭stdout和stderr,这些孩子被父母关闭在调用fork()之前的过程 - 我假设这些流被传递给子进程。如何判断一个流是否在调用fclose之前在C中关闭()

我怎么能告诉我们,如果一个流之前尝试用C关闭后关闭它使用类似fclose(stdout)

UNIX上的C程序希望文件描述符0,1和2在启动时打开。如果你不想让他们去任何地方,打开/dev/nulldup它到那些文件描述符。

如果你在该级别的工作,你可能不应该使用C标准库的缓冲FILE指针(stdin & co),而是与其基本的file descriptor整数本身。

你应该能够做一些无害的操作,例如文件上的lseek(fd, 0, SEEK_SET)来检测底层描述符是否有效。

您可以使用ftell()来检查。 如果它返回-1,那么你的流大多是关闭的。

在调用fclose()之后,任何使用 的流都会导致未定义的行为。

因此,如果是FILE *标准输出,则根本不能再使用stdout,甚至不能检查其是否有效/开放。

您可以直接使用stdout的文件描述符,它是fd 1。

struct stat stbuf; 
if(fstat(1,&stbuf) == -1) { 
    if(errno == EBADF) { 
    stdout isn't open/valid 
    } 
} 
+0

要么缺少的东西或这不工作? 我试着在另一个else {}子句中调用fclose()(意思是fstat的结果不是-1),并且注意到它从未关闭流 - 即使当我确定它是有效的并且打开时 – radai 2010-03-03 10:33:21

+0

看起来确实不可靠,是的。在我的系统上,发生的是fclose(stdout);确实关闭了fd。然而,无论出于什么原因,fclose都会触发加载“/usr/share/nls/nls.alias”,现在它会*获取fd 1 - 以及以下fstat成功 - 但现在指的是/ usr/share/nls/nls.alias“,如果事情按不同的顺序调用,情况可能会有所不同,在'strace'下运行你的程序来看看会发生什么,你最好接受cafs的建议,并且不要关闭stdin/out/err ,而是将它们重定向到/ dev/null – nos 2010-03-03 17:20:31