[multiple changes]
authorBenjamin Kosnik <bkoz@gcc.gnu.org>
Tue, 8 Jan 2002 19:57:01 +0000 (19:57 +0000)
committerBenjamin Kosnik <bkoz@gcc.gnu.org>
Tue, 8 Jan 2002 19:57:01 +0000 (19:57 +0000)
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

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/fstream.tcc
libstdc++-v3/include/std/fstream
libstdc++-v3/testsuite/27_io/filebuf.cc
libstdc++-v3/testsuite/27_io/filebuf_members.cc

index 6bbb95d..20367fb 100644 (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>
 
index 7f90f2a..1e29e5d 100644 (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();
index 350a691..a04ddf0 100644 (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); 
       }
     };
 
index 5b7f086..2ffaabd 100644 (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();
index d955ef7..ab4a60f 100644 (file)
 // 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;
 }