https://gcc.gnu.org/onlinedocs/libstdc++/manual/errno.html says errno is never set to zero by libstdc++: "The C and POSIX standards guarantee that errno is never set to zero by any library function. The C++ standard has less to say about when errno is or isn't set, but libstdc++ follows the same rule and never sets it to zero." However, libstdc++-v3/config/io/basic_file_stdio.cc sets errno to zero in __basic_file<char>::sys_open (currently line 199). I guess errno is set to zero because sync() two lines below isn't guaranteed to update errno, in which case the loop might run forever if errno happened to be EINTR. Maybe errno should only be set to zero in the case when it is EINTR, the only problematic case, and left untouched otherwise.
I think we should capture the previous value of errno and restore it. I thought I checked for all places this was needed but maybe I only looked in the include and src sub-directories, not the config one.
Created attachment 40966 [details] patch
Comment on attachment 40966 [details] patch It's quite possible that "errno" is a macro for something called "__errno" on some systems, so this would fail to compile. I suggest something like __save_errno instead, and it also needs to be done on line 275.
(In reply to Jonathan Wakely from comment #3) > and it also needs to be done on line 275. why? line 275: https://gcc.gnu.org/viewcvs/gcc/trunk/libstdc%2B%2B-v3/config/io/basic_file_stdio.cc?view=markup#l275
Sorry, I was looking at gcc-6-branch which sets errno=0 in close(), but I removed that on trunk for PR 65411.
Created attachment 40970 [details] patch done.
The bug title says std::ifstream sets errno to zero, but it should never run stdio_filebuf::sys_open. Do you have a testcase for this? We should still fix it even if it only affects a non-standard extension, but it's probably not worth backporting if it doesn't affect std::ifstream.
Author: redi Date: Wed Aug 9 17:52:10 2017 New Revision: 250993 URL: https://gcc.gnu.org/viewcvs?rev=250993&root=gcc&view=rev Log: PR libstdc++/81751 don't call fflush(NULL) PR libstdc++/79820 PR libstdc++/81751 * config/io/basic_file_stdio.cc (sys_open(FILE*, ios_base::openmode)): Call fflush on the stream instead of calling sync() while _M_cfile is null. Restore original value of errno. * testsuite/ext/stdio_filebuf/char/79820.cc: New. * testsuite/ext/stdio_filebuf/char/81751.cc: New. Added: trunk/libstdc++-v3/testsuite/ext/stdio_filebuf/char/79820.cc trunk/libstdc++-v3/testsuite/ext/stdio_filebuf/char/81751.cc Modified: trunk/libstdc++-v3/ChangeLog trunk/libstdc++-v3/config/io/basic_file_stdio.cc
Fixed for GCC 8.
Author: redi Date: Mon Sep 4 16:52:30 2017 New Revision: 251676 URL: https://gcc.gnu.org/viewcvs?rev=251676&root=gcc&view=rev Log: PR libstdc++/81751 don't call fflush(NULL) Backport from mainline 2017-08-09 Jonathan Wakely <jwakely@redhat.com> PR libstdc++/79820 PR libstdc++/81751 * config/io/basic_file_stdio.cc (sys_open(FILE*, ios_base::openmode)): Call fflush on the stream instead of calling sync() while _M_cfile is null. Restore original value of errno. * testsuite/ext/stdio_filebuf/char/79820.cc: New. * testsuite/ext/stdio_filebuf/char/81751.cc: New. Added: branches/gcc-6-branch/libstdc++-v3/testsuite/ext/stdio_filebuf/char/79820.cc branches/gcc-6-branch/libstdc++-v3/testsuite/ext/stdio_filebuf/char/81751.cc Modified: branches/gcc-6-branch/libstdc++-v3/ChangeLog branches/gcc-6-branch/libstdc++-v3/config/io/basic_file_stdio.cc
Author: redi Date: Mon Sep 4 17:09:05 2017 New Revision: 251680 URL: https://gcc.gnu.org/viewcvs?rev=251680&root=gcc&view=rev Log: PR libstdc++/81751 don't call fflush(NULL) Backport from mainline 2017-08-09 Jonathan Wakely <jwakely@redhat.com> PR libstdc++/79820 PR libstdc++/81751 * config/io/basic_file_stdio.cc (sys_open(FILE*, ios_base::openmode)): Call fflush on the stream instead of calling sync() while _M_cfile is null. Restore original value of errno. * testsuite/ext/stdio_filebuf/char/79820.cc: New. * testsuite/ext/stdio_filebuf/char/81751.cc: New. Added: branches/gcc-5-branch/libstdc++-v3/testsuite/ext/stdio_filebuf/char/79820.cc branches/gcc-5-branch/libstdc++-v3/testsuite/ext/stdio_filebuf/char/81751.cc Modified: branches/gcc-5-branch/libstdc++-v3/ChangeLog branches/gcc-5-branch/libstdc++-v3/config/io/basic_file_stdio.cc
Fixed for 5.5, 6.5 and 7,.3
Author: aldyh Date: Wed Sep 13 16:43:11 2017 New Revision: 252358 URL: https://gcc.gnu.org/viewcvs?rev=252358&root=gcc&view=rev Log: PR libstdc++/81751 don't call fflush(NULL) PR libstdc++/79820 PR libstdc++/81751 * config/io/basic_file_stdio.cc (sys_open(FILE*, ios_base::openmode)): Call fflush on the stream instead of calling sync() while _M_cfile is null. Restore original value of errno. * testsuite/ext/stdio_filebuf/char/79820.cc: New. * testsuite/ext/stdio_filebuf/char/81751.cc: New. Added: branches/range-gen2/libstdc++-v3/testsuite/ext/stdio_filebuf/char/79820.cc branches/range-gen2/libstdc++-v3/testsuite/ext/stdio_filebuf/char/81751.cc Modified: branches/range-gen2/libstdc++-v3/ChangeLog branches/range-gen2/libstdc++-v3/config/io/basic_file_stdio.cc