This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFC] Shall we loop on EINTR for fclose too?


Carlo Wood wrote:

This is code from my current project:

while ((failure = (::close(M_fd) == -1)) && errno == EINTR);

I guess that I agree thus ;).

Ok ;)

The below is what I have already regtested on x86/ia64-linux. I mean to apply
it to mainline (where would be further tested on many different archs) on
monday, if I don't receive problematic comments in the meanwhile...


Paolo.

////////////////
2004-08-30  Paolo Carlini  <pcarlini@suse.de>
	    Kenneth C. Schalk  <ken@xorian.net>

	PR libstdc++/17215
	* config/io/basic_file_stdio.cc (__basic_file<char>::close()):
	Check the return value of fclose/sync, loop on EINTR.
	(__basic_file<char>::sys_open): Likewise, for sync.
diff -prN libstdc++-v3-orig/config/io/basic_file_stdio.cc libstdc++-v3/config/io/basic_file_stdio.cc
*** libstdc++-v3-orig/config/io/basic_file_stdio.cc	Sat May 29 16:40:59 2004
--- libstdc++-v3/config/io/basic_file_stdio.cc	Sun Aug 29 12:37:31 2004
*************** namespace std 
*** 189,198 ****
      __basic_file* __ret = NULL;
      if (!this->is_open() && __file)
        {
!  	_M_cfile = __file;
!  	_M_cfile_created = false;
! 	this->sync();
!   	__ret = this;
        }
      return __ret;
    }
--- 189,205 ----
      __basic_file* __ret = NULL;
      if (!this->is_open() && __file)
        {
! 	int __err;
! 	errno = 0;	
! 	do
! 	  __err = this->sync();
! 	while (__err && errno == EINTR);
! 	if (!__err)
! 	  {
! 	    _M_cfile = __file;
! 	    _M_cfile_created = false;
! 	    __ret = this;
! 	  }
        }
      return __ret;
    }
*************** namespace std 
*** 252,263 ****
      __basic_file* __ret = static_cast<__basic_file*>(NULL);
      if (this->is_open())
        {
  	if (_M_cfile_created)
! 	  fclose(_M_cfile);
  	else
! 	  this->sync();
  	_M_cfile = 0;
- 	__ret = this;
        }
      return __ret;
    }
--- 259,281 ----
      __basic_file* __ret = static_cast<__basic_file*>(NULL);
      if (this->is_open())
        {
+ 	// 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/fflush must set
+ 	// errno upon error.
+ 	int __err;
+ 	errno = 0;
  	if (_M_cfile_created)
! 	  do
! 	    __err = fclose(_M_cfile);
! 	  while (__err && errno == EINTR);
  	else
! 	  do
! 	    __err = this->sync();
! 	  while (__err && errno == EINTR);
! 	if (!__err)
! 	  __ret = this;
  	_M_cfile = 0;
        }
      return __ret;
    }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]