[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
This commit is contained in:
Benjamin Kosnik 2002-01-08 19:57:01 +00:00
parent 234e114cff
commit 9fbcb61abb
5 changed files with 108 additions and 37 deletions

View file

@ -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>

View file

@ -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();

View file

@ -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);
}
};

View file

@ -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();

View file

@ -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;
}