This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: [RFC] Shall we loop on EINTR for fclose too?
- From: Paolo Carlini <pcarlini at suse dot de>
- To: Carlo Wood <carlo at alinoe dot com>
- Cc: libstdc++ <libstdc++ at gcc dot gnu dot org>, ken at xorian dot net
- Date: Sun, 29 Aug 2004 16:00:41 +0200
- Subject: Re: [RFC] Shall we loop on EINTR for fclose too?
- References: <412FCCB3.9040601@suse.de> <20040828092151.GA4036@alinoe.com>
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;
}