2016-11-04 283 views
2

我试图找出失败的原因ofstream::close(),并遇到一些我不明白的行为。C++ ofstream:评估关闭()错误

我使用std::ofstreamstd::copy()将数据写入流中,然后使用close()写入文件。如果我引发错误(例如文件系统已满),则failbitclose()设置,但我希望得到更详细的错误描述。

到目前为止,我认为如果系统调用失败,总是会设置errno。但errnoSuccess如果我close()失败后立即检查。

我确定系统调用时使用close()流,因为它会将文件写入文件系统,但那么errno怎么可能不告诉任何有关该问题?所以:

  • 请问ofstream::close()不使用任何系统调用?

如果我明确地调用flush()std::copy()后,再errno正确

No space left on device 

集和failbit设置。随后调用close()也设置故障位。令人惊讶的是errno重置为success

errno手册页:

errno is never set to zero by any system call or library function 

,我没有看到哪些其他功能将重新errno

  • ofstream::close()明确重置errno万一它成功了吗?

关于ofstream的文档我找到并没有说关于errno的约束。

测试Linux x86 g ++ 4.7.3。

回答

1

的确,ofstream :: close()会进行多个系统调用。即使系统调用和C库函数没有将errno设置为零,C++库也可能会这样。至少一些ofstream :: close()的实现将errno设置为0.请参阅下面的注释。

我的建议是关注你使用的东西的文档,不要做出假设。在这种情况下,正如你所指出的,ofstream :: close()的文档没有提及errno,所以在调用ofstream :: close()之后你不应该对errno做任何假设。另一方面,C函数,如close(fd)在文档中特别提到了errno。所以如果你真的需要errno,请改用C函数。

+0

但根据手册页,系统调用不应将'errno'设置为0(成功)。在这种情况下使用C函数可能是更好的选择,但是我不得不放弃更通用的方法(C++流)的优势。 – radix

+0

我的理解是,errno的manpage只说没有系统调用,或者C库会将errno设置为0.但是它不会限制其他代码(如用户代码或C++库)将errno设置为0.我研究了C++系统源代码并找到ofstream :: close()调用basic_filebuf :: close(),调用__basic_file :: close(),根据至少一个实现,将errno设置为0.请参阅https://opensource.apple.com/ source/libstdcxx/libstdcxx-52/src/basic_file.cc –

+0

我已经接受了,但实际上认为......下面应该部分进入答案:_ofstream :: close()可以将errno设置为0,并且至少在一些执行_ – radix