This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Patch] Fix libstdc++/9533, 2nd


Hi again,

this version takes into account Nathan's comments and adds the
new non-interactive testcase.

Tested x86-linux, as usual.

Paolo.

//////////
2003-03-03  Paolo Carlini  <pcarlini at unitus dot it>
	    Petur Runolfsson  <peturr02 at ru dot is>

	PR libstdc++/9533
	* config/io/basic_file_stdio.h
	(__basic_file<char>::no_block, block): New, declare.
	* config/io/basic_file_stdio.cc
	(__basic_file<char>::no_block, block): Define.
	(__basic_file<char>::_M_open_mode): Remove #ifdef code.
	(__basic_file<char>::open): Remove #ifdef code.
	* include/bits/fstream.tcc (basic_filebuf::open): Wrap
	underflow() in _M_file.no_block and _M_file.block.
	* testsuite/27_io/filebuf_members.cc (test_07): Add.
diff -urN libstdc++-v3-curr/config/io/basic_file_stdio.cc libstdc++-v3/config/io/basic_file_stdio.cc
--- libstdc++-v3-curr/config/io/basic_file_stdio.cc	2003-02-04 23:42:32.000000000 +0100
+++ libstdc++-v3/config/io/basic_file_stdio.cc	2003-03-03 22:13:40.000000000 +0100
@@ -74,11 +74,7 @@
     if (__testi && !__testo && !__testt && !__testa)
       {
 	strcpy(__c_mode, "r");
-#if defined (O_NONBLOCK)
-	__p_mode |=  O_RDONLY | O_NONBLOCK;
-#else
 	__p_mode |=  O_RDONLY;
-#endif
       }
     if (__testi && __testo && !__testt && !__testa)
       {
@@ -154,19 +150,39 @@
 	if ((_M_cfile = fopen(__name, __c_mode)))
 	  {
 	    _M_cfile_created = true;
-
-#if defined (F_SETFL) && defined (O_NONBLOCK)
-	    // Set input to nonblocking for fifos.
-	    if (__mode & ios_base::in)
-	      fcntl(this->fd(), F_SETFL, O_NONBLOCK);
-#endif
-
 	    __ret = this;
 	  }
       }
     return __ret;
   }
-  
+
+  int
+  __basic_file<char>::no_block()
+  {
+    int __fdflags;
+#if defined (F_SETFL) && defined (F_GETFL) && defined (O_NONBLOCK)
+    if (this->is_open())
+      {
+	__fdflags = fcntl(this->fd(), F_GETFL);
+	fcntl(this->fd(), F_SETFL, O_NONBLOCK);
+      }
+#endif
+    return __fdflags;
+  }
+
+  void
+#if defined (F_SETFL) && defined (F_GETFL) && defined (O_NONBLOCK)
+  __basic_file<char>::block(int __fdflags)
+#else
+  __basic_file<char>::block(int)
+#endif
+  {
+#if defined (F_SETFL) && defined (F_GETFL) && defined (O_NONBLOCK)
+    if (this->is_open())
+      fcntl(this->fd(), F_SETFL, __fdflags & ~O_NONBLOCK);
+#endif	    
+  }  
+
   bool 
   __basic_file<char>::is_open() const 
   { return _M_cfile != 0; }
diff -urN libstdc++-v3-curr/config/io/basic_file_stdio.h libstdc++-v3/config/io/basic_file_stdio.h
--- libstdc++-v3-curr/config/io/basic_file_stdio.h	2002-04-30 21:04:35.000000000 +0200
+++ libstdc++-v3/config/io/basic_file_stdio.h	2003-03-03 22:13:04.000000000 +0100
@@ -76,6 +76,12 @@
       sys_open(int __fd, ios_base::openmode __mode, bool __del);
 
       int
+      no_block();
+
+      void
+      block(int __fdflags);
+
+      int
       sys_getc();
 
       int
diff -urN libstdc++-v3-curr/include/bits/fstream.tcc libstdc++-v3/include/bits/fstream.tcc
--- libstdc++-v3-curr/include/bits/fstream.tcc	2003-03-02 13:21:05.000000000 +0100
+++ libstdc++-v3/include/bits/fstream.tcc	2003-03-03 22:09:13.000000000 +0100
@@ -97,12 +97,17 @@
 	      _M_set_indeterminate();
 
 	      // Set input buffer to something real.
-	      // NB: Must open in non-blocking way to do this, or must
-	      // set the initial position in a different manner than
-	      // using underflow.
+	      // To do this must switch to non-blocking mode, call
+	      // underflow, return to blocking mode. This complexity
+	      // is needed in order to deal correctly both with files
+	      // and pipes (libstdc++/9533).
  	      if (__mode & ios_base::in && _M_buf_allocated)
- 		this->underflow();
-	      
+		{
+		  int __fdflags = _M_file.no_block();
+		  this->underflow();
+		  _M_file.block(__fdflags);
+		}
+			      
 	      if ((__mode & ios_base::ate)
 		  && this->seekoff(0, ios_base::end, __mode) < 0)
 		{
diff -urN libstdc++-v3-curr/testsuite/27_io/filebuf_members.cc libstdc++-v3/testsuite/27_io/filebuf_members.cc
--- libstdc++-v3-curr/testsuite/27_io/filebuf_members.cc	2003-02-04 19:08:45.000000000 +0100
+++ libstdc++-v3/testsuite/27_io/filebuf_members.cc	2003-03-03 22:26:33.000000000 +0100
@@ -217,6 +217,63 @@
   VERIFY( r == NULL );
 }
 
+// libstdc++/9533
+void test_07()
+{
+  bool test = true;
+  using namespace std;
+
+  const int count = 10000;
+
+  signal(SIGPIPE, SIG_IGN);
+  unlink("zzz");
+  
+  if (0 != mkfifo("zzz", S_IRWXU))
+    {
+      VERIFY( false );
+    }
+  
+  int fval = fork();
+  if (fval == -1)
+    {
+      unlink("zzz");
+      VERIFY( false );
+    }
+  else if (fval == 0)
+    {
+      filebuf ofbuf;
+      ofbuf.open("zzz", ios_base::out);
+      VERIFY( ofbuf.is_open() );
+      sleep(1);
+
+      for (int i = 0; i < count; ++i)
+	ofbuf.sputc(i % 100);
+
+      ofbuf.pubsync();
+      sleep(1);
+      ofbuf.close();
+      exit(0);
+    }
+
+  filebuf ifbuf;
+  ifbuf.open("zzz", ios_base::in);
+  VERIFY( ifbuf.is_open() );
+
+  for (int j = 0; j < count; ++j)
+    {
+      int c1 = ifbuf.sbumpc();
+      VERIFY( c1 == j % 100 );
+    }
+
+  int c6 = ifbuf.sbumpc();
+  VERIFY( c6 == filebuf::traits_type::eof() );
+
+  sleep(2);
+  ifbuf.close();
+
+  unlink("zzz");
+}
+
 int
 main()
 {
@@ -226,6 +283,7 @@
   test_04();
   test_05();
   test_06();
+  test_07();
   return 0;
 }
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]