aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Kosnik <bkoz@gcc.gnu.org>2002-01-08 19:57:01 +0000
committerBenjamin Kosnik <bkoz@gcc.gnu.org>2002-01-08 19:57:01 +0000
commit9fbcb61abb9860a9f508311bb5b5181ed625896f (patch)
tree4d2a0e09142e4c57137a2006fd234e9d7f7b0f64
parent234e114cffc7dd651aacc601069d25498f894673 (diff)
downloadgcc-9fbcb61abb9860a9f508311bb5b5181ed625896f.zip
gcc-9fbcb61abb9860a9f508311bb5b5181ed625896f.tar.gz
gcc-9fbcb61abb9860a9f508311bb5b5181ed625896f.tar.bz2
[multiple changes]
2002-01-08 Benjamin Kosnik <bkoz@redhat.com> 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 <jfardo@laurelnetworks.com> Brad Garcia <garsh@attbi.com> * testsuite/27_io/filebuf_members.cc: Add test. From-SVN: r48654
-rw-r--r--libstdc++-v3/ChangeLog15
-rw-r--r--libstdc++-v3/include/bits/fstream.tcc43
-rw-r--r--libstdc++-v3/include/std/fstream11
-rw-r--r--libstdc++-v3/testsuite/27_io/filebuf.cc15
-rw-r--r--libstdc++-v3/testsuite/27_io/filebuf_members.cc61
5 files changed, 108 insertions, 37 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 6bbb95d..20367fb 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,18 @@
+2002-01-08 Benjamin Kosnik <bkoz@redhat.com>
+
+ 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 <jfardo@laurelnetworks.com>
+ Brad Garcia <garsh@attbi.com>
+
+ * testsuite/27_io/filebuf_members.cc: Add test.
+
2002-01-07 Benjamin Kosnik <bkoz@redhat.com>
Craig Rodrigues <rodrigc@mediaone.net>
diff --git a/libstdc++-v3/include/bits/fstream.tcc b/libstdc++-v3/include/bits/fstream.tcc
index 7f90f2a..1e29e5d 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 350a691..a04ddf0 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 5b7f086..2ffaabd 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 d955ef7..ab4a60f 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 <iostream>
#include <fstream>
#include <unistd.h>
+#include <signal.h>
#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
#include <testsuite_hooks.h>
// 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 <jfardo@laurelnetworks.com>, Brad Garcia <garsh@attbi.com>
+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;
}