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


Hi,

the below, which is the result of today's exchanges with Pétur,
fixes the problem by setting O_NONBLOCK only for initializing the
buffer, otherwise leaving O_NONBLOCK clear, as explained by Nathan.

Tested x86-linux.

Ok trunk and 3_3?

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/narrow_stream_objects.cc (test11): 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 18:42:56.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,43 @@
 	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;
   }
-  
+
+  void
+#if defined (F_SETFL) && defined (F_GETFL) && defined (O_NONBLOCK)
+  __basic_file<char>::no_block(int& __fdflags)
+#else
+  __basic_file<char>::no_block(int&)
+#endif
+  {
+    if (this->is_open())
+      {
+#if defined (F_SETFL) && defined (F_GETFL) && defined (O_NONBLOCK)
+	__fdflags = fcntl(this->fd(), F_GETFL);
+	fcntl(this->fd(), F_SETFL, O_NONBLOCK);
+#endif
+      }
+  }
+
+  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 (this->is_open())
+      {
+#if defined (F_SETFL) && defined (F_GETFL) && defined (O_NONBLOCK)
+	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 18:39:47.000000000 +0100
@@ -75,6 +75,12 @@
       __basic_file*
       sys_open(int __fd, ios_base::openmode __mode, bool __del);
 
+      void
+      no_block(int& __fdflags);
+
+      void
+      block(int& __fdflags);
+
       int
       sys_getc();
 
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 18:56:02.000000000 +0100
@@ -97,12 +97,18 @@
 	      _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(__fdflags);
+		  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/narrow_stream_objects.cc libstdc++-v3/testsuite/27_io/narrow_stream_objects.cc
--- libstdc++-v3-curr/testsuite/27_io/narrow_stream_objects.cc	2002-08-09 08:00:46.000000000 +0200
+++ libstdc++-v3/testsuite/27_io/narrow_stream_objects.cc	2003-03-03 19:03:42.000000000 +0100
@@ -204,6 +204,24 @@
   cout << "_M_gcount: "<< cin.gcount() << endl;
 }
 
+// libstdc++/9533
+// http://gcc.gnu.org/ml/gcc-bugs/2003-03/msg00076.html
+void
+test11()
+{
+  using namespace std;
+
+  ifstream in ("/dev/tty");
+  ofstream out ("/dev/tty");
+  
+  in.tie(&out);
+  
+  out << "Enter a number: ";
+  int i;
+  in >> i;
+  out << "You entered: " << i << endl;
+}
+
 int 
 main()
 {
@@ -218,5 +236,6 @@
   // test08();
   // test09();
   // test10();
+  // test11();
   return 0;
 }

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