+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>
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
_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
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;
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);
// 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,
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();
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
close(void)
{
if (!_M_filebuf.close())
- setstate(ios_base::failbit);
+ this->setstate(ios_base::failbit);
}
};
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
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();
// 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
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");
int second_fd = fb.fd();
- bool test = first_fd == second_fd;
+ test = first_fd == second_fd;
#ifdef DEBUG_ASSERT
assert(test);
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;
}