From: Benjamin Kosnik Date: Tue, 8 Jan 2002 19:57:01 +0000 (+0000) Subject: [multiple changes] X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9fbcb61abb9860a9f508311bb5b5181ed625896f;p=gcc.git [multiple changes] 2002-01-08 Benjamin Kosnik libstdc++/2913 libstdc++/4879 * include/bits/fstream.tcc (filebuf::_M_really_overflow): Test return value of _M_file->sync(). (filebuf::showmanyc): Check for is_open. * include/std/fstream (filebuf::sync): Tweak. * testsuite/27_io/filebuf.cc: Tweak. 2002-01-08 John Fardo Brad Garcia * testsuite/27_io/filebuf_members.cc: Add test. From-SVN: r48654 --- diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index 6bbb95db627..20367fb7dd1 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,18 @@ +2002-01-08 Benjamin Kosnik + + libstdc++/2913 + libstdc++/4879 + * include/bits/fstream.tcc (filebuf::_M_really_overflow): Test + return value of _M_file->sync(). + (filebuf::showmanyc): Check for is_open. + * include/std/fstream (filebuf::sync): Tweak. + * testsuite/27_io/filebuf.cc: Tweak. + +2002-01-08 John Fardo + Brad Garcia + + * testsuite/27_io/filebuf_members.cc: Add test. + 2002-01-07 Benjamin Kosnik Craig Rodrigues diff --git a/libstdc++-v3/include/bits/fstream.tcc b/libstdc++-v3/include/bits/fstream.tcc index 7f90f2a383e..1e29e5d17c8 100644 --- a/libstdc++-v3/include/bits/fstream.tcc +++ b/libstdc++-v3/include/bits/fstream.tcc @@ -182,11 +182,19 @@ namespace std if (this->is_open()) { bool __testput = _M_out_cur && _M_out_beg < _M_out_end; - if (__testput) - _M_really_overflow(traits_type::eof()); - - // NB: Do this here so that re-opened filebufs will be cool... - _M_pback_destroy(); + if (__testput + && _M_really_overflow(traits_type::eof()) != traits_type::eof()) + { + // NB: Do this here so that re-opened filebufs will be cool... + _M_mode = ios_base::openmode(0); + _M_destroy_internal_buffer(); + + _M_pback_destroy(); + if (_M_pback) + { + delete [] _M_pback; + _M_pback = NULL; + } #if 0 // XXX not done @@ -196,16 +204,8 @@ namespace std _M_really_overflow(traits_type::eof()); } #endif - - _M_mode = ios_base::openmode(0); - _M_destroy_internal_buffer(); - - if (_M_pback) - { - delete [] _M_pback; - _M_pback = NULL; + __ret = this; } - __ret = this; } // Can actually allocate this file as part of an open and never @@ -227,7 +227,7 @@ namespace std streamsize __ret = -1; bool __testin = _M_mode & ios_base::in; - if (__testin) + if (__testin && this->is_open()) { if (_M_in_cur < _M_in_end) __ret = _M_in_end - _M_in_cur; @@ -420,7 +420,7 @@ namespace std if (__plen) __len = _M_file->xsputn(_M_out_beg, __plen); - if (__c !=traits_type::eof()) + if (__c != traits_type::eof()) { char_type __pending = traits_type::to_char_type(__c); __len += _M_file->xsputn(&__pending, 1); @@ -429,12 +429,11 @@ namespace std // NB: Need this so that external byte sequence reflects // internal buffer. - _M_file->sync(); if (__len == __plen) - { - _M_set_indeterminate(); - __ret = traits_type::not_eof(__c); - } + _M_set_indeterminate(); + + if (!_M_file->sync()) + __ret = traits_type::not_eof(__c); #else // Part one: Allocate temporary conversion buffer on // stack. Convert internal buffer plus __c (ie, @@ -468,7 +467,7 @@ namespace std streamsize __len = _M_file->xsputn(__conv_buf, __plen); // NB: Need this so that external byte sequence reflects // internal buffer. - _M_file->sync(); + _M_file->sync(); // XXX error check if (__len == __plen) { _M_set_indeterminate(); diff --git a/libstdc++-v3/include/std/fstream b/libstdc++-v3/include/std/fstream index 350a691d68c..a04ddf098dd 100644 --- a/libstdc++-v3/include/std/fstream +++ b/libstdc++-v3/include/std/fstream @@ -182,12 +182,11 @@ namespace std sync(void) { bool __testput = _M_out_cur && _M_out_beg < _M_out_end; - if (__testput) - { - // Make sure that libio resyncs its idea of the file position - // with the external file. - _M_file->sync(); + // Make sure that the internal buffer resyncs its idea of + // the file position with the external file. + if (__testput && !_M_file->sync()) + { // Need to restore current position. This interpreted as // the position of the external byte sequence (_M_file) // plus the offset in the current internal buffer @@ -354,7 +353,7 @@ namespace std close(void) { if (!_M_filebuf.close()) - setstate(ios_base::failbit); + this->setstate(ios_base::failbit); } }; diff --git a/libstdc++-v3/testsuite/27_io/filebuf.cc b/libstdc++-v3/testsuite/27_io/filebuf.cc index 5b7f086b45c..2ffaabd97ec 100644 --- a/libstdc++-v3/testsuite/27_io/filebuf.cc +++ b/libstdc++-v3/testsuite/27_io/filebuf.cc @@ -347,16 +347,15 @@ bool test03() { for (int i = 50; i < 32 + 29; ++i) fb_02.sputc(char(i)); fb_02.pubseekoff(0, std::ios_base::beg, std::ios_base::out); - strmsz_1 = fb_02.in_avail(); c1 = fb_02.sgetc(); + strmsz_1 = fb_02.in_avail(); c2 = fb_02.sungetc(); - strmsz_2 = fb_02.in_avail(); c3 = fb_02.sgetc(); - VERIFY( c1 == c2 ); - VERIFY( c3 == c2 ); - VERIFY( c1 == c3 ); - VERIFY( c2 == traits_type::eof() ); - VERIFY( strmsz_1 == strmsz_2 ); + strmsz_2 = fb_02.in_avail(); + VERIFY( c1 != c2 ); + VERIFY( c2 == c3 ); + VERIFY( c1 == traits_type::eof() ); + VERIFY( strmsz_1 != strmsz_2 ); //test for _in_cur == _in_end fb_03.pubseekoff(0, std::ios_base::end); strmsz_1 = fb_03.in_avail(); // -1 cuz at the end @@ -382,7 +381,7 @@ bool test03() { fb_02.pubsync(); // 27filebuf-2.txt == 53 bytes after this. strmsz_2 = fb_02.in_avail(); - VERIFY( strmsz_2 == -1 ); + VERIFY( strmsz_2 == 1 ); VERIFY( strmsz_2 == strmsz_1 ); strmsz_1 = fb_03.in_avail(); fb_03.pubsync(); diff --git a/libstdc++-v3/testsuite/27_io/filebuf_members.cc b/libstdc++-v3/testsuite/27_io/filebuf_members.cc index d955ef7ed1f..ab4a60f3094 100644 --- a/libstdc++-v3/testsuite/27_io/filebuf_members.cc +++ b/libstdc++-v3/testsuite/27_io/filebuf_members.cc @@ -23,9 +23,13 @@ // various tests for filebuf::open() and filebuf::close() including // the non-portable functionality in the libstdc++-v3 IO library +#include #include #include +#include #include +#include +#include #include // verify that std::filebuf doesn't close files that it didn't open @@ -80,6 +84,7 @@ test_01() int test_02() { + bool test = true; int first_fd = ::open(name_01, O_RDONLY); VERIFY( first_fd != -1 ); FILE* first_file = ::fdopen(first_fd, "r"); @@ -88,7 +93,7 @@ test_02() int second_fd = fb.fd(); - bool test = first_fd == second_fd; + test = first_fd == second_fd; #ifdef DEBUG_ASSERT assert(test); @@ -97,10 +102,64 @@ test_02() return test; } +// libstdc++/2913, libstdc++/4879 +// John Fardo , Brad Garcia +void +test_03() +{ + signal(SIGPIPE, SIG_IGN); + + if (0 != mkfifo("xxx", S_IRWXU)) + { + std::cerr << "failed to creat fifo" << std::endl; + exit(-1); + } + + int fval = fork(); + if (fval == -1) + { + std::cerr << "failed to fork" << std::endl; + unlink("xxx"); + exit(-1); + } + else if (fval == 0) + { + std::ifstream ifs("xxx"); + sleep(1); + ifs.close(); + exit(0); + } + + std::ofstream ofs("xxx"); + sleep(2); + ofs.put('t'); + + /* + * ISO/IED 14882:1998(E) 27.8.1.10.4 + * + * void close(); + * + * Effects: Calls rdbuf()->close() and, if that function fails + * (returns a null pointer), calls setstate(failbit)... + */ + ofs.close(); + if (!(ofs.rdstate() & std::ios::failbit)) + { + std::cerr << "fail bit was not set!" << std::endl; + unlink("xxx"); + exit(-1); + } + + unlink("xxx"); + exit(0); +} + int main() { test_01(); test_02(); + + test_03(); return 0; }