This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
[Patch] Fix libstdc++/9533, 2nd
- From: Paolo Carlini <pcarlini at unitus dot it>
- To: "libstdc++ at gcc dot gnu dot org" <libstdc++ at gcc dot gnu dot org>
- Date: Mon, 03 Mar 2003 23:29:20 +0100
- Subject: [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;
}