This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[Patch] Fix libstdc++/9533
- From: Paolo Carlini <pcarlini at unitus dot it>
- To: "libstdc++ at gcc dot gnu dot org" <libstdc++ at gcc dot gnu dot org>
- Cc: Benjamin Kosnik <bkoz at redhat dot com>
- Date: Mon, 03 Mar 2003 19:27:14 +0100
- Subject: [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;
}