为什么在破坏函数函数中fstream Zero ernno

why fstream zero errno in the destructor function

本文关键字:函数 fstream Zero ernno 为什么      更新时间:2023-10-16

示例代码是这样的:

void testFuncErrno()
{
    fstream fstr;
    fstr.exceptions(std::ifstream::failbit | std::ifstream::badbit);
    try
    {
        fstr.open("/mnt/virtualfs/test.ss", ofstream::out);
        fstr << "test" << endl;
    }
    catch(std::ifstream::failure e)
    {
        cout << "func catch errno is:" << errno << ":" << strerror(errno) << endl;
        cout << "good?" << (fstr.good()?"yes":"no") << endl;
    }
}
int main(int argc, char *argv[])
{
    try
    {
        errno = 0;
        testFuncErrno();
        cout << "0 st errno is:" << errno << ":" << strerror(errno) << endl;
    }
    catch(std::ifstream::failure e)
    {
        cout << "catch errno is:" << errno << ":" << strerror(errno) << endl;
    }
    pause();
    return 0;
}

当磁盘已满时,我想捕获ERRNO,但是当功能结束时,Errno似乎将设置为零。我使用ddd跟踪源代码,并找到了下面的一些注释,但是从errno说明中:

errno在程序启动时设置为零,标准C库的任何功能都可以将其值修改为与零不同的值,通常以信号特定类别的错误类别(无库函数将其值设置为零一旦更改)。

这让我有些困惑,为什么关闭将Errno设置为零?

  __basic_file<char>* 
  __basic_file<char>::close()
  { 
    __basic_file* __ret = static_cast<__basic_file*>(NULL);
    if (this->is_open())
      {
    int __err = 0;
    if (_M_cfile_created)
      {
        **// In general, no need to zero errno in advance if checking
        // for error first. However, C89/C99 (at variance with IEEE
        // 1003.1, f.i.) do not mandate that fclose must set errno
        // upon error.**
        errno = 0;
        do
          __err = fclose(_M_cfile);
        while (__err && errno == EINTR);
      }
    _M_cfile = 0;
    if (!__err)
      __ret = this;
      }
    return __ret;
  }

在调用已知要设置errno的库函数之前,将ERRNO设置为零是一个好练习,并且仅在函数返回返回值表示故障的值后才检查ERRNO。这是因为crandard库函数可以将ERRNO的值设置为非零,无论是否存在错误,只要在函数的描述中未记录Errno的使用。

因此,如果您仅在程序开始时初始化errno,则无法保证通过函数调用设置错误值。

将错误设置为0之前,请在调用fclose()确认Errno所拥有的值是由FCLOSE()设置的,而没有其他函数。

您可能会在以下讨论以下讨论:https://www.securecoding.cert.org/confluence/pages/viewpage.action?pageID=6619179