diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index afd5f672699a3d6adef967409d0d3e29e816b500..7165b8e6cc87d201e418ef75b5bef0112d5345cf 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,14 @@
+2003-05-26  Benjamin Kosnik  <bkoz@redhat.com>
+
+	PR libstdc++/9339
+	* include/std/std_fstream.h (basic_filebuf::_M_overflow): Remove.
+	(_M_pback): No array necessary.
+	* include/bits/fstream.tcc (basic_filebuf::_M_overflow): Add
+	unbuffered case, coalesec into ...
+	(basic_filebuf::overflow): ...this.
+	* testsuite/27_io/basic_filebuf/sputn/char/9339.cc: New.
+	* testsuite/27_io/basic_filebuf/sputc/char/2.cc: Unbuffered.
+	
 2003-05-24  Nathanael Nerode  <neroden@gcc.gnu.org>
 
 	* libsupc++/Makefile.am, libsupc++/cxxabi.h, libsupc++/del_op.cc,
@@ -58,6 +69,7 @@
 
 2003-05-22  Brad Spencer  <spencer@infointeractive.com>
 
+	PR libstdc++/10106
 	* configure.in: Add Solaris cross bits.
 
 2003-05-21  Danny Smith  <dannysmith@users.sourceforge.net>
diff --git a/libstdc++-v3/include/bits/fstream.tcc b/libstdc++-v3/include/bits/fstream.tcc
index cda0bacd9f9cf7f7f711b1ca9081edfcd17834fb..9bbb5cc1a52927f28322110aff6ccce51bd70ca1 100644
--- a/libstdc++-v3/include/bits/fstream.tcc
+++ b/libstdc++-v3/include/bits/fstream.tcc
@@ -73,7 +73,7 @@ namespace std
     basic_filebuf() : __streambuf_type(), _M_file(&_M_lock), 
     _M_state_cur(__state_type()), _M_state_beg(__state_type()), 
     _M_buf(NULL), _M_buf_size(BUFSIZ), _M_buf_allocated(false),
-    _M_last_overflowed(false), _M_pback_cur_save(0),
+    _M_last_overflowed(false), _M_filepos(0), _M_pback_cur_save(0),
     _M_pback_end_save(0), _M_pback_init(false), _M_codecvt(0)
     { 
       this->_M_buf_unified = true; 	  
@@ -125,7 +125,7 @@ namespace std
 	      const bool __testput = this->_M_out_beg < this->_M_out_lim;
 
 	      if (__testput 
-		  && traits_type::eq_int_type(_M_overflow(__eof), __eof))
+		  && traits_type::eq_int_type(this->overflow(), __eof))
 		__testfail = true;
 
 #if 0
@@ -133,7 +133,7 @@ namespace std
 	      if (_M_last_overflowed)
 		{
 		  _M_output_unshift();
-		  _M_overflow(__eof);
+		  this->overflow();
 		}
 #endif
 	    }
@@ -204,7 +204,7 @@ namespace std
 
 	  // Sync internal and external buffers.
 	  if (__testout && this->_M_out_beg < this->_M_out_lim)
-	    _M_overflow();
+	    this->overflow();
 
 	  if (_M_buf_size > 1)
 	    {
@@ -321,67 +321,49 @@ namespace std
       return __ret;
     }
 
-  template<typename _CharT, typename _Traits>
-    typename basic_filebuf<_CharT, _Traits>::int_type 
-    basic_filebuf<_CharT, _Traits>::
-    _M_overflow(int_type __c)
-    {
-      int_type __ret = traits_type::eof();
-      const bool __testeof = traits_type::eq_int_type(__c, __ret);
-      const bool __testput = this->_M_out_beg < this->_M_out_lim;
-
-      if (__testput)
- 	{
- 	  // Need to restore current position. The position of the
- 	  // external byte sequence (_M_file) corresponds to
- 	  // _M_filepos, and we need to move it to _M_out_beg for the
- 	  // write.
-	  if (_M_filepos != this->_M_out_beg)
-	    _M_file.seekoff(this->_M_out_beg - _M_filepos, ios_base::cur);
-
-	  // If appropriate, append the overflow char.
-	  if (!__testeof)
-	    *this->_M_out_lim++ = traits_type::to_char_type(__c);
-
-	  // Convert pending sequence to external representation,
-	  // output. 
-	  if (_M_convert_to_external(this->_M_out_beg,
-				     this->_M_out_lim - this->_M_out_beg)
-	      && (!__testeof || (__testeof && !_M_file.sync())))
-	    {
-	      _M_set_buffer(0);
-	      __ret = traits_type::not_eof(__c);
-	    }
-	}
-      _M_last_overflowed = true;	
-      return __ret;
-    }
-
   template<typename _CharT, typename _Traits>
     typename basic_filebuf<_CharT, _Traits>::int_type 
     basic_filebuf<_CharT, _Traits>::
     overflow(int_type __c)
     {
       int_type __ret = traits_type::eof();
-      const bool __testput = this->_M_out_cur < this->_M_out_end;
+      const bool __testeof = traits_type::eq_int_type(__c, __ret);
       const bool __testout = this->_M_mode & ios_base::out;
       
-      // Perhaps set below in _M_overflow.
-      _M_last_overflowed = false;
-
       if (__testout)
 	{
-	  if (traits_type::eq_int_type(__c, traits_type::eof()))
-	    __ret = traits_type::not_eof(__c);
-	  else if (__testput)
+	  if (this->_M_out_beg < this->_M_out_lim)
+	    {
+	      // Need to restore current position. The position of the
+	      // external byte sequence (_M_file) corresponds to
+	      // _M_filepos, and we need to move it to _M_out_beg for
+	      // the write.
+	      if (_M_filepos != this->_M_out_beg)
+		_M_file.seekoff(this->_M_out_beg - _M_filepos, ios_base::cur);
+
+	      // If appropriate, append the overflow char.
+	      if (!__testeof)
+		*this->_M_out_lim++ = traits_type::to_char_type(__c);
+	      
+	      // Convert pending sequence to external representation,
+	      // output.
+	      if (_M_convert_to_external(this->_M_out_beg,
+					 this->_M_out_lim - this->_M_out_beg)
+		  && (!__testeof || (__testeof && !_M_file.sync())))
+		{
+		  _M_set_buffer(0);
+		  __ret = traits_type::not_eof(__c);
+		}
+	    }
+	  else
 	    {
- 	      *this->_M_out_cur = traits_type::to_char_type(__c);
-	      _M_move_out_cur(1);
-	      __ret = traits_type::not_eof(__c);
+	      // Unbuffered.
+	      char_type __conv = traits_type::to_char_type(__c);
+	      if (!__testeof && _M_convert_to_external(&__conv, 1))
+		__ret = __c;
 	    }
-	  else 
-	    __ret = this->_M_overflow(__c);
 	}
+      _M_last_overflowed = true;	
       return __ret;
     }
   
diff --git a/libstdc++-v3/include/bits/streambuf.tcc b/libstdc++-v3/include/bits/streambuf.tcc
index f80a815aa42723293798026e4faea9a84c52290c..5b76c40f9288c85d77f47eb8aa028d6ca27cef2d 100644
--- a/libstdc++-v3/include/bits/streambuf.tcc
+++ b/libstdc++-v3/include/bits/streambuf.tcc
@@ -115,7 +115,7 @@ namespace std
       while (__ret < __n)
 	{
 	  const size_t __buf_len = _M_in_end - _M_in_cur;
-	  if (__buf_len > 0)
+	  if (__buf_len)
 	    {
 	      const size_t __remaining = __n - __ret;
 	      const size_t __len = std::min(__buf_len, __remaining);
@@ -149,7 +149,7 @@ namespace std
       while (__ret < __n)
 	{
 	  const size_t __buf_len = _M_out_end - _M_out_cur;
-	  if (__buf_len > 0)
+	  if (__buf_len)
 	    {
 	      const size_t __remaining = __n - __ret;
 	      const size_t __len = std::min(__buf_len, __remaining);
@@ -161,7 +161,7 @@ namespace std
 
 	  if (__ret < __n)
 	    {
-	      const int_type __c = this->overflow(traits_type::to_int_type(*__s));
+	      int_type __c = this->overflow(traits_type::to_int_type(*__s));
 	      if (!traits_type::eq_int_type(__c, traits_type::eof()))
 		{
 		  ++__ret;
diff --git a/libstdc++-v3/include/std/std_fstream.h b/libstdc++-v3/include/std/std_fstream.h
index 27794881c75d5e1e7b491df70b6dabdfa3a3c86c..9faf73730062947996d42b69e3ff53ec0e20f832 100644
--- a/libstdc++-v3/include/std/std_fstream.h
+++ b/libstdc++-v3/include/std/std_fstream.h
@@ -158,7 +158,7 @@ namespace std
        *  @note pbacks of over one character are not currently supported.
        *  @endif
       */
-      char_type			_M_pback[1]; 
+      char_type			_M_pback; 
       char_type*		_M_pback_cur_save;
       char_type*		_M_pback_end_save;
       bool			_M_pback_init; 
@@ -177,7 +177,7 @@ namespace std
 	  {
 	    _M_pback_cur_save = this->_M_in_cur;
 	    _M_pback_end_save = this->_M_in_end;
-	    this->setg(_M_pback, _M_pback, _M_pback + 1);
+	    this->setg(&_M_pback, &_M_pback, &_M_pback + 1);
 	    _M_pback_init = true;
 	  }
       }
@@ -191,8 +191,8 @@ namespace std
 	if (_M_pback_init)
 	  {
 	    // Length _M_in_cur moved in the pback buffer.
-	    const size_t __off_cur = this->_M_in_cur - _M_pback;
-	    this->setg(this->_M_buf, _M_pback_cur_save + __off_cur, 
+	    const size_t __off = this->_M_in_cur == &_M_pback ? 0 : 1;
+	    this->setg(this->_M_buf, _M_pback_cur_save + __off, 
 		       _M_pback_end_save);
 	    _M_pback_init = false;
 	  }
@@ -311,19 +311,6 @@ namespace std
       virtual int_type
       pbackfail(int_type __c = _Traits::eof());
 
-      // NB: For what the standard expects of the overflow function,
-      // see _M_overflow(), below. Because basic_streambuf's
-      // sputc/sputn call overflow directly, and the complications of
-      // this implementation's setting of the initial pointers all
-      // equal to _M_buf when initializing, it seems essential to have
-      // this in actuality be a helper function that checks for the
-      // eccentricities of this implementation, and then call
-      // overflow() if indeed the buffer is full.
-
-      // [documentation is inherited]
-      virtual int_type
-      overflow(int_type __c = _Traits::eof());
-
       // Stroustrup, 1998, p 648
       // The overflow() function is called to transfer characters to the
       // real output destination when the buffer is full. A call to
@@ -336,8 +323,8 @@ namespace std
        *  @doctodo
        *  @endif
       */
-      int_type
-      _M_overflow(int_type __c = _Traits::eof());
+      virtual int_type
+      overflow(int_type __c = _Traits::eof());
 
       // Convert internal byte sequence to external, char-based
       // sequence via codecvt.
@@ -389,7 +376,7 @@ namespace std
 	    off_type __off = this->_M_out_cur - this->_M_out_lim;
 
 	    // _M_file.sync() will be called within
-	    if (traits_type::eq_int_type(_M_overflow(), traits_type::eof()))
+	    if (traits_type::eq_int_type(this->overflow(), traits_type::eof()))
 	      __ret = -1;
 	    else if (__off)
 	      _M_file.seekoff(__off, ios_base::cur);
@@ -444,7 +431,7 @@ namespace std
 
       // This function sets the pointers of the internal buffer, both get
       // and put areas. Typically, __off == _M_in_end - _M_in_beg upon
-      // _M_underflow; __off == 0 upon _M_overflow, seekoff, open, setbuf.
+      // _M_underflow; __off == 0 upon overflow, seekoff, open, setbuf.
       // 
       // NB: _M_out_end - _M_out_beg == _M_buf_size - 1, since _M_buf_size
       // reflects the actual allocated memory and the last cell is reserved
diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/sputc/char/2.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/sputc/char/2.cc
new file mode 100644
index 0000000000000000000000000000000000000000..f6a4ae8b0db37e230c37a0f4ca0d7fe485c47523
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/sputc/char/2.cc
@@ -0,0 +1,129 @@
+// 2003-05-21 Benjamin Kosnik  <bkoz@redhat.com>
+
+// 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 <testsuite_hooks.h>
+
+// @require@ %-*.tst %-*.txt
+// @diff@ %-*.tst %*.txt
+
+// NB: This test assumes that _M_buf_size == 40, and not the usual
+// buffer_size length of BUFSIZ (8192), so that overflow/underflow can be
+// simulated a bit more readily.
+// NRB (Nota Really Bene): setting it to 40 breaks the test, as intended.
+const int buffer_size = 8192;
+//const int buffer_size = 40;
+
+const char name_01[] = "filebuf_virtuals-1.txt"; // file with data in it
+const char name_02[] = "filebuf_virtuals-2.txt"; // empty file, need to create
+const char name_03[] = "filebuf_virtuals-3.txt"; // empty file, need to create
+
+class derived_filebuf: public std::filebuf
+{
+ public:
+  void
+  set_size(int_type __size) { _M_buf_size = __size; }
+};
+
+derived_filebuf fb_01; // in 
+derived_filebuf fb_02; // out
+derived_filebuf fb_03; // in | out
+
+// Initialize filebufs to be the same size regardless of platform.
+void test03()
+{
+  fb_01.set_size(buffer_size);
+  fb_02.set_size(buffer_size);
+  fb_03.set_size(buffer_size);
+}
+
+// Test overloaded virtual functions.
+void test05() 
+{
+  typedef std::filebuf::int_type 	int_type;
+  typedef std::filebuf::traits_type 	traits_type;
+  typedef std::filebuf::pos_type 	pos_type;
+  typedef std::filebuf::off_type 	off_type;
+  typedef size_t 			size_type;
+
+  bool 					test = true;
+  std::filebuf 				f_tmp;
+  std::streamsize 			strmsz_1, strmsz_2;
+  std::streamoff  			strmof_1, strmof_2;
+  int 					i = 0, j = 0, k = 0;
+
+  // Unbuffered
+  fb_01.pubsetbuf(0, 0);
+  fb_02.pubsetbuf(0, 0);
+  fb_03.pubsetbuf(0, 0);
+
+  fb_01.open(name_01, std::ios_base::in);
+  fb_02.open(name_02, std::ios_base::out | std::ios_base::trunc);
+  fb_03.open(name_03, std::ios_base::out | std::ios_base::in | std::ios_base::trunc);
+
+  int_type c1 = fb_01.sbumpc();
+  int_type c2 = fb_02.sbumpc();
+  int_type c3 = fb_01.sbumpc();
+  int_type c4 = fb_02.sbumpc();
+  int_type c5 = fb_03.sbumpc();
+  int_type c6 = fb_01.sgetc();
+  int_type c7 = fb_02.sgetc();
+  int_type c8 = fb_01.sgetc();
+  int_type c9 = fb_02.sgetc();
+
+  // PUT
+  // int_type sputc(char_type c)
+  // if out_cur not avail, return overflow(traits_type::to_int_type(c)) 
+  // else, stores c at out_cur,
+  // increments out_cur, and returns c as int_type
+  // strmsz_1 = fb_03.in_avail();  // XXX valid for in|out??
+  c1 = fb_02.sputc('a'); 
+  c2 = fb_03.sputc('b'); 
+  VERIFY( c1 != c2 );
+  c1 = fb_02.sputc('c'); 
+  c2 = fb_03.sputc('d'); 
+  VERIFY( c1 != c2 );
+  // strmsz_2 = fb_03.in_avail();
+  // VERIFY( strmsz_1 != strmsz_2 );
+  for (int i = 50; i <= 90; ++i) 
+    c2 = fb_02.sputc(char(i));
+  // 27filebuf-2.txt == ac23456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX
+  // fb_02._M_out_cur = '2'
+  strmsz_1 = fb_03.in_avail();
+  for (int i = 50; i <= 90; ++i) 
+    c2 = fb_03.sputc(char(i));
+  strmsz_2 = fb_03.in_avail();
+  // VERIFY( strmsz_1 != strmsz_2 );
+  // VERIFY( strmsz_1 > 0 );
+  // VERIFY( strmsz_2 > 0 );
+  // 27filebuf-2.txt == bd23456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWX
+  // fb_02._M_out_cur = '2'
+  c3 = fb_01.sputc('a'); // should be EOF because this is read-only
+  VERIFY( c3 == traits_type::eof() );
+}
+
+main() 
+{
+  test03();
+  test05();
+  return 0;
+}
diff --git a/libstdc++-v3/testsuite/27_io/basic_filebuf/sputn/char/9339.cc b/libstdc++-v3/testsuite/27_io/basic_filebuf/sputn/char/9339.cc
new file mode 100644
index 0000000000000000000000000000000000000000..37a4145044919bc1e8ccd0c4e3a074932e3fa6da
--- /dev/null
+++ b/libstdc++-v3/testsuite/27_io/basic_filebuf/sputn/char/9339.cc
@@ -0,0 +1,46 @@
+// 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.
+
+#include <fstream>
+#include <testsuite_hooks.h>
+
+// libstdc++/9339
+void test01()
+{
+  using namespace std;
+  bool test = true;
+
+  filebuf fbuf01;
+  int len = 35;
+  fbuf01.pubsetbuf(0, 0);
+  fbuf01.open("tmp_9339", ios_base::out | ios_base::trunc);
+  streamsize s1 = fbuf01.sputn("Pete Goldlust @ Carl Hammer Gallery", len);
+  VERIFY( s1 == len );
+
+  filebuf fbuf02;
+  char buf[256];
+  fbuf02.open("tmp_9339", ios_base::in);
+  streamsize s2 = fbuf02.sgetn(buf, 256);
+  VERIFY( s2 == len );
+}
+
+int main()
+{
+  test01();
+  return 0;
+}