2002-04-30 Benjamin Kosnik <bkoz@redhat.com>
+ * include/ext/stdio_filebuf.h: New file.
+ * include/ext/enc_filebuf.h: New file.
+ * config/io/basic_file_stdio.h (__basic_file::sys_open): Add fd ctor.
+ * config/io/basic_file_stdio.cc: Same.
+ * include/bits/fstream.tcc (filebuf::_M_allocate_internal_buffer):
+ Remove _M_unbuf hacks.
+ (filebuf::_M_destroy_internal_buffer): Same.
+ (filebuf::filebuf(cfile, openmode, int_type): Remove definition.
+ (filebuf::fd): Remove.
+ * include/std/std_fstream.h (filebuf::_M_unbuf): Remove.
+ (filebuf::filebuf(__c_file*, openmode, int_type)): Remove.
+ (filebuf::fd): Remove.
+ * src/ios.cc (ios_base::_S_ios_create): Change to use specialized
+ filebufs.
+ (ios_base::_S_ios_destroy): Same.
+ * src/misc-inst.cc (file_filebuf<char>): Add instantiation.
+ * include/Makefile.am (ext_headers): Add ext_filebuf.h,
+ stdio_filebuf.h. * include/Makefile.in: Regenerate.
+
+2002-04-30 Benjamin Kosnik <bkoz@redhat.com>
+
PR libstdc++/6511
* config/os/solaris/solaris2.7/bits/ctype_noninline.h: Fix typo.
__basic_file* __ret = NULL;
if (!this->is_open() && __file)
{
- _M_cfile = __file;
- _M_cfile_created = false;
+ _M_cfile = __file;
+ _M_cfile_created = false;
+ __ret = this;
+ }
+ return __ret;
+ }
+
+ __basic_file<char>*
+ __basic_file<char>::sys_open(int __fd, ios_base::openmode __mode,
+ bool __del)
+ {
+ __basic_file* __ret = NULL;
+ int __p_mode = 0;
+ int __rw_mode = 0;
+ char __c_mode[4];
+
+ _M_open_mode(__mode, __p_mode, __rw_mode, __c_mode);
+ if (!this->is_open() && (_M_cfile = fdopen(__fd, __c_mode)))
+ {
+ // Iff __del is true, then close will fclose the fd.
+ _M_cfile_created = __del;
+
+ if (__fd == 0)
+ setvbuf(_M_cfile, reinterpret_cast<char*>(NULL), _IONBF, 0);
+
__ret = this;
}
return __ret;
int
__basic_file<char>::sys_getc()
{ return getc(_M_cfile); }
-
+
int
__basic_file<char>::sys_ungetc(int __c)
{ return ungetc(__c, _M_cfile); }
}
bool
- __basic_file<char>::is_open() const { return _M_cfile != 0; }
+ __basic_file<char>::is_open() const
+ { return _M_cfile != 0; }
int
- __basic_file<char>::fd() { return fileno(_M_cfile) ; }
+ __basic_file<char>::fd()
+ { return fileno(_M_cfile) ; }
__basic_file<char>*
__basic_file<char>::close()
}
int
- __basic_file<char>::sync() { return fflush(_M_cfile); }
+ __basic_file<char>::sync()
+ { return fflush(_M_cfile); }
} // namespace std
open(const char* __name, ios_base::openmode __mode, int __prot = 0664);
__basic_file*
- sys_open(__c_file* __file, ios_base::openmode __mode);
+ sys_open(__c_file* __file, ios_base::openmode);
+
+ __basic_file*
+ sys_open(int __fd, ios_base::openmode __mode, bool __del);
int
sys_getc();
ext_builddir = ./ext
ext_headers = \
${ext_srcdir}/algorithm \
+ ${ext_srcdir}/enc_filebuf.h \
+ ${ext_srcdir}/stdio_filebuf.h \
${ext_srcdir}/functional \
${ext_srcdir}/hash_map \
${ext_srcdir}/hash_set \
ext_builddir = ./ext
ext_headers = \
${ext_srcdir}/algorithm \
+ ${ext_srcdir}/enc_filebuf.h \
+ ${ext_srcdir}/stdio_filebuf.h \
${ext_srcdir}/functional \
${ext_srcdir}/hash_map \
${ext_srcdir}/hash_set \
{
_M_buf_size = _M_buf_size_opt;
- if (_M_buf_size != 1)
+ // Allocate internal buffer.
+ try { _M_buf = new char_type[_M_buf_size]; }
+ catch(...)
{
- // Allocate internal buffer.
- try { _M_buf = new char_type[_M_buf_size]; }
- catch(...)
- {
- delete [] _M_buf;
- __throw_exception_again;
- }
- _M_buf_allocated = true;
+ delete [] _M_buf;
+ __throw_exception_again;
}
- else
- _M_buf = _M_unbuf;
+ _M_buf_allocated = true;
}
}
this->setg(NULL, NULL, NULL);
this->setp(NULL, NULL);
}
- else
- {
- if (_M_buf == _M_unbuf)
- {
- _M_buf = NULL;
- this->setg(NULL, NULL, NULL);
- this->setp(NULL, NULL);
- }
- }
}
template<typename _CharT, typename _Traits>
basic_filebuf<_CharT, _Traits>::
- basic_filebuf()
- : __streambuf_type(), _M_file(&_M_lock), _M_state_cur(__state_type()),
- _M_state_beg(__state_type()), _M_buf_allocated(false),
- _M_last_overflowed(false)
+ basic_filebuf() : __streambuf_type(), _M_file(&_M_lock),
+ _M_state_cur(__state_type()), _M_state_beg(__state_type()),
+ _M_buf_allocated(false), _M_last_overflowed(false)
{ _M_buf_unified = true; }
template<typename _CharT, typename _Traits>
- basic_filebuf<_CharT, _Traits>::
- basic_filebuf(__c_file* __f, ios_base::openmode __mode, int_type __s)
- : __streambuf_type(), _M_file(&_M_lock), _M_state_cur(__state_type()),
- _M_state_beg(__state_type()), _M_buf_allocated(false),
- _M_last_overflowed(false)
- {
- _M_buf_unified = true;
- _M_file.sys_open(__f, __mode);
- if (this->is_open())
- {
- _M_mode = __mode;
- if (__s)
- {
- _M_buf_size_opt = __s;
- _M_allocate_internal_buffer();
- _M_set_indeterminate();
- }
- }
- }
-
- template<typename _CharT, typename _Traits>
- int
- basic_filebuf<_CharT, _Traits>::
- fd()
- { return _M_file.fd(); }
-
- template<typename _CharT, typename _Traits>
typename basic_filebuf<_CharT, _Traits>::__filebuf_type*
basic_filebuf<_CharT, _Traits>::
open(const char* __s, ios_base::openmode __mode)
--- /dev/null
+// __enc_traits layer for filebuf -*- C++ -*-
+
+// Copyright (C) 2002 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.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#include <fstream>
+#include <locale>
+
+namespace __gnu_cxx
+{
+ // Custom traits type with __enc_traits for state type, all other bits
+ // equivalent to the required char_traits instantiations.
+ template<typename _CharT>
+ struct enc_char_traits: public std::char_traits<_CharT>
+ {
+ typedef std::__enc_traits state_type;
+ };
+
+ template<typename _CharT>
+ class enc_filebuf
+ : public std::basic_filebuf<_CharT, enc_char_traits<_CharT> >
+ {
+ public:
+ typedef typename enc_char_traits<_CharT>::state_type state_type;
+
+ enc_filebuf(state_type& __state)
+ : std::basic_filebuf<_CharT, enc_char_traits<_CharT> >()
+ {
+ // Set state type to something useful.
+ // Something more than copyconstructible is needed here, so
+ // require copyconstructible + assignment operator.
+ __glibcpp_class_requires(state_type, _SGIAssignableConcept);
+ _M_state_cur = __state;
+ _M_state_cur._M_init();
+ };
+ };
+} // namespace __gnu_cxx
--- /dev/null
+// File descriptor layer for filebuf -*- C++ -*-
+
+// Copyright (C) 2002 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.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+#include <fstream>
+
+namespace __gnu_cxx
+{
+ template<typename _CharT, typename _Traits = std::char_traits<_CharT> >
+ class stdio_filebuf : public std::basic_filebuf<_CharT, _Traits>
+ {
+ public:
+ // Types:
+ typedef _CharT char_type;
+ typedef _Traits traits_type;
+ typedef typename traits_type::int_type int_type;
+ typedef typename traits_type::pos_type pos_type;
+ typedef typename traits_type::off_type off_type;
+
+ protected:
+ // Stack-based buffer for unbuffered input.
+ char_type _M_unbuf[4];
+
+ public:
+ stdio_filebuf(int __fd, std::ios_base::openmode __mode, bool __del,
+ int_type __size);
+
+ stdio_filebuf(std::__c_file* __f, std::ios_base::openmode __mode,
+ int_type __size = static_cast<int_type>(BUFSIZ));
+
+ virtual
+ ~stdio_filebuf();
+
+ int
+ fd()
+ { return _M_file.fd(); }
+ };
+
+ template<typename _CharT, typename _Traits>
+ stdio_filebuf<_CharT, _Traits>::~stdio_filebuf()
+ { }
+
+ template<typename _CharT, typename _Traits>
+ stdio_filebuf<_CharT, _Traits>::
+ stdio_filebuf(int __fd, std::ios_base::openmode __mode, bool __del,
+ int_type __size)
+ {
+ _M_file.sys_open(__fd, __mode, __del);
+ if (this->is_open())
+ {
+ _M_mode = __mode;
+ _M_buf_size_opt = __size;
+
+ if (__size > 0 && __size < 4)
+ {
+ _M_buf = _M_unbuf;
+ _M_buf_size = __size;
+ }
+ else
+ _M_allocate_internal_buffer();
+
+ _M_set_indeterminate();
+ }
+ }
+
+ template<typename _CharT, typename _Traits>
+ stdio_filebuf<_CharT, _Traits>::
+ stdio_filebuf(std::__c_file* __f, std::ios_base::openmode __mode,
+ int_type __size)
+ {
+ _M_file.sys_open(__f, __mode);
+ if (this->is_open())
+ {
+ _M_mode = __mode;
+ _M_buf_size_opt = __size;
+
+ if (__size > 0 && __size < 4)
+ {
+ _M_buf = _M_unbuf;
+ _M_buf_size = __size;
+ }
+ else
+ _M_allocate_internal_buffer();
+
+ _M_set_indeterminate();
+ }
+ }
+} // namespace __gnu_cxx
__state_type _M_state_cur;
__state_type _M_state_beg;
- // Set iff _M_buf is allocated memory from _M_allocate_internal_buffer..
+ // Set iff _M_buf is allocated memory from _M_allocate_internal_buffer.
bool _M_buf_allocated;
- // Stack-based buffer for unbuffered input.
- char_type _M_unbuf[4];
-
// XXX Needed?
bool _M_last_overflowed;
// Constructors/destructor:
basic_filebuf();
- // Non-standard ctor:
- basic_filebuf(__c_file* __f, ios_base::openmode __mode,
- int_type __s = static_cast<int_type>(BUFSIZ));
-
- // Non-standard member:
- int
- fd();
-
virtual
~basic_filebuf()
{
#include <istream>
#include <ostream>
#include <locale>
+#include <ext/stdio_filebuf.h>
// On AIX, and perhaps other systems, library initialization order is
// not guaranteed. For example, the static initializers for the main
fake_ostream cerr;
fake_ostream clog;
- typedef char fake_filebuf[sizeof(filebuf)]
- __attribute__ ((aligned(__alignof__(filebuf))));
+ typedef char fake_filebuf[sizeof(__gnu_cxx::stdio_filebuf<char>)]
+ __attribute__ ((aligned(__alignof__(__gnu_cxx::stdio_filebuf<char>))));
fake_filebuf buf_cout;
fake_filebuf buf_cin;
fake_filebuf buf_cerr;
fake_wostream wcerr;
fake_wostream wclog;
- typedef char fake_wfilebuf[sizeof(wfilebuf)]
- __attribute__ ((aligned(__alignof__(wfilebuf))));
+ typedef char fake_wfilebuf[sizeof(__gnu_cxx::stdio_filebuf<wchar_t>)]
+ __attribute__ ((aligned(__alignof__(__gnu_cxx::stdio_filebuf<wchar_t>))));
fake_wfilebuf buf_wcout;
fake_wfilebuf buf_wcin;
fake_wfilebuf buf_wcerr;
#include <ostream>
#include <istream>
#include <fstream>
-
#include <bits/atomicity.h>
+#include <ext/stdio_filebuf.h>
namespace std
{
extern ostream cout;
extern ostream cerr;
extern ostream clog;
- extern filebuf buf_cout;
- extern filebuf buf_cin;
- extern filebuf buf_cerr;
+
+ using __gnu_cxx::stdio_filebuf;
+ extern stdio_filebuf<char> buf_cout;
+ extern stdio_filebuf<char> buf_cin;
+ extern stdio_filebuf<char> buf_cerr;
#ifdef _GLIBCPP_USE_WCHAR_T
extern wistream wcin;
extern wostream wcout;
extern wostream wcerr;
extern wostream wclog;
- extern wfilebuf buf_wcout;
- extern wfilebuf buf_wcin;
- extern wfilebuf buf_wcerr;
+
+ extern stdio_filebuf<wchar_t> buf_wcout;
+ extern stdio_filebuf<wchar_t> buf_wcin;
+ extern stdio_filebuf<wchar_t> buf_wcerr;
#endif
// Definitions for static const data members of __ios_flags.
void
ios_base::Init::_S_ios_create(bool __sync)
{
- int __out_bufsize = __sync ? 0 : static_cast<int>(BUFSIZ);
- int __in_bufsize = __sync ? 1 : static_cast<int>(BUFSIZ);
+ int __out_size = __sync ? 0 : static_cast<int>(BUFSIZ);
+ int __in_size = __sync ? 1 : static_cast<int>(BUFSIZ);
// NB: The file globals.cc creates the four standard files
// with NULL buffers. At this point, we swap out the dummy NULL
// [io]stream objects and buffers with the real deal.
- new (&buf_cout) filebuf(stdout, ios_base::out, __out_bufsize);
- new (&buf_cin) filebuf(stdin, ios_base::in, __in_bufsize);
- new (&buf_cerr) filebuf(stderr, ios_base::out, __out_bufsize);
+ new (&buf_cout) stdio_filebuf<char>(stdout, ios_base::out, __out_size);
+ new (&buf_cin) stdio_filebuf<char>(stdin, ios_base::in, __in_size);
+ new (&buf_cerr) stdio_filebuf<char>(stderr, ios_base::out, __out_size);
new (&cout) ostream(&buf_cout);
new (&cin) istream(&buf_cin);
new (&cerr) ostream(&buf_cerr);
cerr.flags(ios_base::unitbuf);
#ifdef _GLIBCPP_USE_WCHAR_T
- new (&buf_wcout) wfilebuf(stdout, ios_base::out, __out_bufsize);
- new (&buf_wcin) wfilebuf(stdin, ios_base::in, __in_bufsize);
- new (&buf_wcerr) wfilebuf(stderr, ios_base::out, __out_bufsize);
+ new (&buf_wcout) stdio_filebuf<wchar_t>(stdout, ios_base::out, __out_size);
+ new (&buf_wcin) stdio_filebuf<wchar_t>(stdin, ios_base::in, __in_size);
+ new (&buf_wcerr) stdio_filebuf<wchar_t>(stderr, ios_base::out, __out_size);
new (&wcout) wostream(&buf_wcout);
new (&wcin) wistream(&buf_wcin);
new (&wcerr) wostream(&buf_wcerr);
// Explicitly call dtors to free any memory that is dynamically
// allocated by filebuf ctor or member functions, but don't
// deallocate all memory by calling operator delete.
- buf_cout.~filebuf();
- buf_cin.~filebuf();
- buf_cerr.~filebuf();
+ buf_cout.~stdio_filebuf();
+ buf_cin.~stdio_filebuf();
+ buf_cerr.~stdio_filebuf();
+
#ifdef _GLIBCPP_USE_WCHAR_T
- buf_wcout.~wfilebuf();
- buf_wcin.~wfilebuf();
- buf_wcerr.~wfilebuf();
+ buf_wcout.~stdio_filebuf();
+ buf_wcin.~stdio_filebuf();
+ buf_wcerr.~stdio_filebuf();
#endif
}
#include <istream>
#include <ostream>
#include <iomanip>
+#include <ext/stdio_filebuf.h>
// NB: Unnecessary if the .h headers already include these.
#ifndef _GLIBCPP_FULLY_COMPLIANT_HEADERS
__copy_streambufs(basic_ios<wchar_t>&, basic_streambuf<wchar_t>*,
basic_streambuf<wchar_t>*);
#endif
+
+ using __gnu_cxx::stdio_filebuf;
+ template class stdio_filebuf<char>;
+#ifdef _GLIBCPP_USE_WCHAR_T
+ template class stdio_filebuf<wchar_t>;
+#endif
} //std
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <ext/stdio_filebuf.h>
#include <testsuite_hooks.h>
const char name_01[] = "filebuf_members-1.tst";
FILE* f2 = fopen(name_01, "r");
VERIFY( f2 != NULL );
{
- std::filebuf fb(f2, std::ios_base::in, 512);
+ __gnu_cxx::stdio_filebuf<char> fb(f2, std::ios_base::in, 512);
}
close_num = fclose(f2);
VERIFY( close_num == 0 );
VERIFY( first_fd != -1 );
FILE* first_file = ::fdopen(first_fd, "r");
VERIFY( first_file != NULL );
- std::filebuf fb (first_file, std::ios_base::in);
+ __gnu_cxx::stdio_filebuf<char> fb(first_file, std::ios_base::in);
int second_fd = fb.fd();