aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3
diff options
context:
space:
mode:
authorPaolo Carlini <pcarlini@suse.de>2003-11-12 01:14:34 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2003-11-12 01:14:34 +0000
commitdfad48c6e89fcfed91f31f3a23b4c904a7455d11 (patch)
tree7871f58252a0edac33cfa8d880d21937f3504787 /libstdc++-v3
parenta5966c9ef9036294c09f0729f9950b90b1d1c3b5 (diff)
downloadgcc-dfad48c6e89fcfed91f31f3a23b4c904a7455d11.zip
gcc-dfad48c6e89fcfed91f31f3a23b4c904a7455d11.tar.gz
gcc-dfad48c6e89fcfed91f31f3a23b4c904a7455d11.tar.bz2
re PR libstdc++/12875 (Weird behaviour in basic_filebuf::setbuf())
2003-11-11 Paolo Carlini <pcarlini@suse.de> PR libstdc++/12875 * include/bits/fstream.tcc (setbuf): Don't do anything after open(), in particular don't discard data. (_M_allocate_internal_buffer): Tweak to not allocate memory in case the buffer is provided by the user via setbuf. * include/ext/stdio_filebuf.h: Tweak comment. * testsuite/27_io/basic_filebuf/setbuf/char/12875-1.cc: New. * testsuite/27_io/basic_filebuf/setbuf/char/12875-2.cc: Likewise. * testsuite/27_io/basic_filebuf/setbuf/char/2.cc: Tweak, now setbuf does nothing after open(). * testsuite/27_io/basic_filebuf/setbuf/char/3.cc: Likewise. From-SVN: r73477
Diffstat (limited to 'libstdc++-v3')
-rw-r--r--libstdc++-v3/ChangeLog14
-rw-r--r--libstdc++-v3/include/bits/fstream.tcc49
-rw-r--r--libstdc++-v3/include/ext/stdio_filebuf.h10
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_filebuf/setbuf/char/12875-1.cc57
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_filebuf/setbuf/char/12875-2.cc55
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_filebuf/setbuf/char/2.cc2
-rw-r--r--libstdc++-v3/testsuite/27_io/basic_filebuf/setbuf/char/3.cc8
7 files changed, 155 insertions, 40 deletions
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 1df66ab..791cee3 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,17 @@
+2003-11-11 Paolo Carlini <pcarlini@suse.de>
+
+ PR libstdc++/12875
+ * include/bits/fstream.tcc (setbuf): Don't do anything
+ after open(), in particular don't discard data.
+ (_M_allocate_internal_buffer): Tweak to not allocate memory
+ in case the buffer is provided by the user via setbuf.
+ * include/ext/stdio_filebuf.h: Tweak comment.
+ * testsuite/27_io/basic_filebuf/setbuf/char/12875-1.cc: New.
+ * testsuite/27_io/basic_filebuf/setbuf/char/12875-2.cc: Likewise.
+ * testsuite/27_io/basic_filebuf/setbuf/char/2.cc: Tweak, now
+ setbuf does nothing after open().
+ * testsuite/27_io/basic_filebuf/setbuf/char/3.cc: Likewise.
+
2003-11-11 Doug Gregor <gregod@cs.rpi.edu>
* docs/html/debug.html: Document libstdc++ debug mode.
diff --git a/libstdc++-v3/include/bits/fstream.tcc b/libstdc++-v3/include/bits/fstream.tcc
index 5649741..a2daab5 100644
--- a/libstdc++-v3/include/bits/fstream.tcc
+++ b/libstdc++-v3/include/bits/fstream.tcc
@@ -44,15 +44,15 @@ namespace std
basic_filebuf<_CharT, _Traits>::
_M_allocate_internal_buffer()
{
- if (!_M_buf_allocated && this->_M_buf_size)
+ // Allocate internal buffer only if one doesn't already exist
+ // (either allocated or provided by the user via setbuf).
+ if (!_M_buf_allocated && !this->_M_buf)
{
- // Allocate internal buffer.
this->_M_buf = new char_type[this->_M_buf_size];
_M_buf_allocated = true;
}
}
- // Both close and setbuf need to deallocate internal buffers, if it exists.
template<typename _CharT, typename _Traits>
void
basic_filebuf<_CharT, _Traits>::
@@ -213,8 +213,8 @@ namespace std
else
{
// Worst-case number of external bytes.
- // XXX Not done encoding() == -1.
- const int __enc = _M_codecvt->encoding();
+ // XXX Not done encoding() == -1.
+ const int __enc = _M_codecvt->encoding();
streamsize __blen; // Minimum buffer size.
streamsize __rlen; // Number of chars to read.
if (__enc > 0)
@@ -539,29 +539,22 @@ namespace std
basic_filebuf<_CharT, _Traits>::
setbuf(char_type* __s, streamsize __n)
{
- if (!this->is_open() && __s == 0 && __n == 0)
- this->_M_buf_size = 1;
- else if (__s && __n > 0)
- {
- // This is implementation-defined behavior, and assumes that
- // an external char_type array of length __n exists and has
- // been pre-allocated. If this is not the case, things will
- // quickly blow up. When __n > 1, __n - 1 positions will be
- // used for the get area, __n - 1 for the put area and 1
- // position to host the overflow char of a full put area.
- // When __n == 1, 1 position will be used for the get area
- // and 0 for the put area, as in the unbuffered case above.
-
- // Step 1: Destroy the current internal array.
- _M_destroy_internal_buffer();
-
- // Step 2: Use the external array.
- this->_M_buf = __s;
- this->_M_buf_size = __n;
- _M_reading = false;
- _M_writing = false;
- _M_set_buffer(-1);
- }
+ if (!this->is_open())
+ if (__s == 0 && __n == 0)
+ this->_M_buf_size = 1;
+ else if (__s && __n > 0)
+ {
+ // This is implementation-defined behavior, and assumes that
+ // an external char_type array of length __n exists and has
+ // been pre-allocated. If this is not the case, things will
+ // quickly blow up. When __n > 1, __n - 1 positions will be
+ // used for the get area, __n - 1 for the put area and 1
+ // position to host the overflow char of a full put area.
+ // When __n == 1, 1 position will be used for the get area
+ // and 0 for the put area, as in the unbuffered case above.
+ this->_M_buf = __s;
+ this->_M_buf_size = __n;
+ }
return this;
}
diff --git a/libstdc++-v3/include/ext/stdio_filebuf.h b/libstdc++-v3/include/ext/stdio_filebuf.h
index 8750f58..9e04807 100644
--- a/libstdc++-v3/include/ext/stdio_filebuf.h
+++ b/libstdc++-v3/include/ext/stdio_filebuf.h
@@ -66,9 +66,7 @@ namespace __gnu_cxx
* @param fd An open file descriptor.
* @param mode Same meaning as in a standard filebuf.
* @param del Whether to close the file on destruction.
- * @param size Optimal or preferred size of internal buffer, in bytes.
- * Note that it includes a position for the overflow char,
- * therefore, can't be smaller than 2.
+ * @param size Optimal or preferred size of internal buffer, in chars.
*
* This constructor associates a file stream buffer with an open
* POSIX file descriptor. Iff @a del is true, then the associated
@@ -80,10 +78,8 @@ namespace __gnu_cxx
/**
* @param f An open @c FILE*.
* @param mode Same meaning as in a standard filebuf.
- * @param size Optimal or preferred size of internal buffer, in bytes.
- * Defaults to system's @c BUFSIZ. Note that it includes
- * a position for the overflow char, therefore, can't be
- * smaller than 2.
+ * @param size Optimal or preferred size of internal buffer, in chars.
+ * Defaults to system's @c BUFSIZ.
*
* This constructor associates a file stream buffer with an open
* C @c FILE*. The @c FILE* will not be automatically closed when the
diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/setbuf/char/12875-1.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/setbuf/char/12875-1.cc
new file mode 100644
index 0000000..5013b87
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/setbuf/char/12875-1.cc
@@ -0,0 +1,57 @@
+// Copyright (C) 2003 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 27.8.1.4 Overridden virtual functions
+
+#include <fstream>
+#include <cstdio>
+#include <cstring>
+#include <testsuite_hooks.h>
+
+// libstdc++/12875
+void test01()
+{
+ using namespace std;
+ bool test __attribute__((unused)) = true;
+
+ const char* name = "tmp_setbuf4";
+ static char buf[1024];
+
+ FILE* out = fopen(name, "w");
+ fputs("Hello, world", out);
+ fclose(out);
+
+ filebuf in;
+ in.open(name, ios_base::in);
+ char str[256];
+ streamsize r = in.sgetn(str, 6);
+ VERIFY( r == 6 );
+ VERIFY( !memcmp(str, "Hello,", 6) );
+ in.pubsetbuf(buf, 1024);
+ r = in.sgetn(str, 6);
+ VERIFY( r == 6 );
+ VERIFY( !memcmp(str, " world", 6) );
+ in.close();
+}
+
+// libstdc++/12875
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/setbuf/char/12875-2.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/setbuf/char/12875-2.cc
new file mode 100644
index 0000000..c50a5ed
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/setbuf/char/12875-2.cc
@@ -0,0 +1,55 @@
+// Copyright (C) 2003 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 2, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// 27.8.1.4 Overridden virtual functions
+
+#include <fstream>
+#include <cstdio>
+#include <cstring>
+#include <testsuite_hooks.h>
+
+// libstdc++/12875
+void test02()
+{
+ using namespace std;
+ bool test __attribute__((unused)) = true;
+
+ const char* name = "tmp_setbuf5";
+ static char buf[1024];
+
+ filebuf out;
+ out.open(name, ios_base::out);
+ streamsize r = out.sputn("Hello,", 6);
+ VERIFY( r == 6 );
+ out.pubsetbuf(buf, 1024);
+ r = out.sputn(" world", 6);
+ VERIFY( r == 6 );
+ VERIFY( out.close() );
+
+ FILE* in = fopen(name, "r");
+ char str[256];
+ fgets(str, 256, in);
+ VERIFY( !strcmp(str, "Hello, world") );
+ fclose(in);
+}
+
+int main()
+{
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/setbuf/char/2.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/setbuf/char/2.cc
index 7cca957..524935a 100644
--- a/libstdc++-v3/testsuite/27_io/basic_filebuf/setbuf/char/2.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/setbuf/char/2.cc
@@ -32,8 +32,8 @@ void test01()
const char* strlit = "how to tell a story and other essays: mark twain";
const size_t strlitsize = std::strlen(strlit);
filebuf fbuf;
- fbuf.open("tmp_setbuf2", ios_base::out);
fbuf.pubsetbuf(buf, 512);
+ fbuf.open("tmp_setbuf2", ios_base::out);
fbuf.sputn(strlit, strlitsize);
VERIFY( std::strncmp(strlit, buf, strlitsize) == 0 );
}
diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/setbuf/char/3.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/setbuf/char/3.cc
index b5512d7..11702dc 100644
--- a/libstdc++-v3/testsuite/27_io/basic_filebuf/setbuf/char/3.cc
+++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/setbuf/char/3.cc
@@ -23,7 +23,7 @@
#include <fstream>
#include <testsuite_hooks.h>
-void test02()
+void test03()
{
using namespace std;
@@ -32,17 +32,17 @@ void test02()
const char* strlit = "how to tell a story and other essays: mark twain";
const size_t strlitsize = std::strlen(strlit);
filebuf fbuf01;
- fbuf01.open("tmp", ios_base::out);
-
// NB: +2 otherwise sputn is optimized to a direct write,
// bypassing the buffer.
fbuf01.pubsetbuf(buf, strlitsize + 2);
+ fbuf01.open("tmp_setbuf3", ios_base::out);
+
fbuf01.sputn(strlit, strlitsize);
VERIFY( std::strncmp(strlit, buf, strlitsize) == 0 );
}
int main()
{
- test02();
+ test03();
return 0;
}