+2001-03-26 Benjamin Kosnik <bkoz@redhat.com>
+
+ * include/bits/basic_file.h (get_fileno): Remove.
+ (_M_fileno): Remove.
+ (_M_cfile_created): Add.
+ (basic_file::basic_file(__c_file_type*, openmode): Add.
+ (basic_file::basic_file(int, const char*, openmode): Remove.
+ * include/bits/fstream.tcc (basic_fstream::basic_filebuf(int __fd,
+ const char*, ios_base::openmode): Don't allocate
+ internal buffers. Turn off internal buffers.
+ (basic_filebuf::overflow): Remove test for null buffer.
+ (basic_filebuf::_M_really_overflow): Same. Allow unbuffered use.
+ * include/bits/streambuf.cc: Tweak.
+ * include/bits/std_ostream.h: Tweak.
+ * config/basic_file_libio.h: Same.
+ * config/basic_file_stdio.h: Same.
+ * src/ios.cc (ios_base::Init::Init()): Unbuffer stdout by default.
+ * testsuite/27_io/filebuf_members.cc: Tweaks.
+ * testsuite/27_io/ios_base_members_static.cc: Tweaks.
+
2001-03-24 Phil Edwards <pme@sources.redhat.com>
* Makefile.am: New targets, doxygen and doxygen-maint.
__basic_file<wchar_t>::doallocate();
#endif
- // Generic definitions for __basic_file
- template<typename _CharT>
- int
- __basic_file<_CharT>::get_fileno(void)
- { return _fileno; }
-
template<typename _CharT>
__basic_file<_CharT>::~__basic_file()
{ _IO_file_finish(this, 0); }
template<typename _CharT>
__basic_file<_CharT>*
- __basic_file<_CharT>::sys_open(int __fd, ios_base::openmode __mode)
+ __basic_file<_CharT>::sys_open(__c_file_type* __f,
+ ios_base::openmode __mode)
{
__basic_file* __ret = NULL;
+ int __fd = fileno(__f);
int __p_mode = 0;
int __rw_mode = _IO_NO_READS + _IO_NO_WRITES;
char __c_mode[4];
if (!_IO_file_is_open(this))
{
_fileno = __fd;
- _flags &= ~(_IO_NO_READS+_IO_NO_WRITES);
+ _flags &= ~(_IO_NO_READS + _IO_NO_WRITES);
_flags |= _IO_DELETE_DONT_CLOSE;
_offset = _IO_pos_BAD;
int __mask = _IO_NO_READS + _IO_NO_WRITES + _IO_IS_APPENDING;
// Generic definitions for __basic_file
template<typename _CharT>
__basic_file<_CharT>::__basic_file(__c_lock* /*__lock*/)
- : _M_fileno(-1), _M_cfile(NULL) { }
+ : _M_cfile(NULL), _M_cfile_created(false) { }
- template<typename _CharT>
- int
- __basic_file<_CharT>::get_fileno(void)
- { return _M_fileno; }
-
template<typename _CharT>
__basic_file<_CharT>::~__basic_file()
{
template<typename _CharT>
__basic_file<_CharT>*
- __basic_file<_CharT>::sys_open(int __fd, ios_base::openmode __mode)
+ __basic_file<_CharT>::sys_open(__c_file_type* __file, ios_base::openmode)
{
__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);
-
- int __dupfd = dup(__fd);
-
- if (__dupfd != -1 && !this->is_open())
+ if (!this->is_open() && __file)
{
- if ((_M_cfile = fdopen(__dupfd, __c_mode)))
- {
- _M_fileno = __dupfd;
- __ret = this;
- }
+ _M_cfile = __file;
+ _M_cfile_created = false;
+ __ret = this;
}
return __ret;
{
if ((_M_cfile = fopen(__name, __c_mode)))
{
- _M_fileno = fileno(_M_cfile);
+ _M_cfile_created = true;
__ret = this;
}
}
template<typename _CharT>
bool
- __basic_file<_CharT>::is_open() { return _M_fileno >= 0; }
+ __basic_file<_CharT>::is_open() { return _M_cfile != 0; }
template<typename _CharT>
__basic_file<_CharT>*
__basic_file<_CharT>::close()
{
__basic_file* __retval = static_cast<__basic_file*>(NULL);
- bool __testopen = fclose(_M_cfile);
- if (!__testopen)
- {
- __retval = this;
- _M_fileno = -1;
- }
+ if (_M_cfile_created && fclose(_M_cfile))
+ __retval = this;
return __retval;
}
#endif
{
#if _GLIBCPP_BASIC_FILE_ENCAPSULATION
- int _M_fileno;
__c_file_type* _M_cfile;
+ bool _M_cfile_created;
#else
# ifdef _GLIBCPP_USE_WCHAR_T
__c_wfile_type _M_wfile;
// just sets __c_file_type->_fileno and the respective _flags bits, and
// returns.
__basic_file*
- sys_open(int __fd, ios_base::openmode __mode);
+ sys_open(__c_file_type* __file, ios_base::openmode __mode);
__basic_file*
close();
bool
is_open();
- // Needed by ios_base::sync_with_stdio.
- int get_fileno(void);
-
// NB: Must match FILE specific jump table starting here--this
// means all virtual functions starting with the dtor must match,
// slot by slot. For glibc-based dystems, this means the _IO_FILE
#include <bits/basic_file_model.h>
#endif // _CPP_BASIC_FILE
-
template<typename _CharT, typename _Traits>
basic_filebuf<_CharT, _Traits>::
- basic_filebuf(int __fd, const char* /*__name*/, ios_base::openmode __mode)
+ basic_filebuf(__c_file_type* __f, ios_base::openmode __mode)
: __streambuf_type(), _M_file(NULL), _M_state_cur(__state_type()),
_M_state_beg(__state_type()), _M_last_overflowed(false)
{
_M_filebuf_init();
- _M_file->sys_open(__fd, __mode);
+ _M_file->sys_open(__f, __mode);
if (this->is_open())
- {
- _M_allocate_buffers();
- _M_mode = __mode;
-
- // XXX So that istream::getc() will only need to get 1 char,
- // as opposed to BUF_SIZE.
- if (__fd == 0)
- _M_buf_size = 1;
-
- this->_M_set_indeterminate();
- }
+ _M_mode = __mode;
}
template<typename _CharT, typename _Traits>
overflow(int_type __c)
{
int_type __ret = traits_type::eof();
- bool __testpos = _M_out_cur && _M_out_cur >= _M_buf + _M_buf_size;
+ bool __testput = _M_out_cur && _M_out_cur < _M_buf + _M_buf_size;
bool __testout = _M_mode & ios_base::out;
if (__testout)
{
- if (!__testpos)
+ if (__testput)
{
*_M_out_cur = traits_type::to_char_type(__c);
_M_out_cur_move(1);
{
int_type __ret = traits_type::eof();
bool __testput = _M_out_cur && _M_out_beg < _M_out_end;
-
- if (__testput)
+ bool __testunbuffered = _M_file && !_M_buf_size;
+
+ if (__testput || __testunbuffered)
{
- bool __testeof = traits_type::eq_int_type(__c, traits_type::eof());
#if 1
int __plen = _M_out_end - _M_out_beg;
- streamsize __len = _M_file->xsputn(_M_out_beg, __plen);
- if (!__testeof)
+ streamsize __len = 0;
+
+ if (__plen)
+ __len = _M_file->xsputn(_M_out_beg, __plen);
+
+ if (__c !=traits_type::eof())
{
- char_type __pending = traits_type::to_char_type(__c);
- __len += _M_file->xsputn(&__pending, 1);
- ++__plen;
+ char_type __pending = traits_type::to_char_type(__c);
+ __len += _M_file->xsputn(&__pending, 1);
+ ++__plen;
}
- traits_type::to_char_type(__c);
+
// NB: Need this so that external byte sequence reflects
// internal buffer.
_M_file->sync();
#include <bits/std_locale.h> // For codecvt
#include <bits/c++threads.h> // For __mutext_type
-namespace std {
-
+namespace std
+{
template<typename _CharT, typename _Traits>
class basic_filebuf : public basic_streambuf<_CharT, _Traits>
{
basic_filebuf();
// Non-standard ctor:
- basic_filebuf(int __fd, const char* __name, ios_base::openmode __mode);
-
+ basic_filebuf(__c_file_type* __f, ios_base::openmode __mode);
+
virtual
~basic_filebuf()
{
setstate (ios_base::failbit);
}
};
-
} // namespace std
#endif
#endif
-#endif /* _CPP_FSTREAM */
+#endif
#endif
#endif /* _CPP_OSTREAM */
+
if (__ret < __n)
{
int_type __c = this->uflow();
- if (traits_type::eq_int_type(__c, traits_type::eof()))
+ if (__c != traits_type::eof())
+ {
+ traits_type::assign(*__s++, traits_type::to_char_type(__c));
+ ++__ret;
+ }
+ else
break;
- traits_type::assign(*__s++, traits_type::to_char_type(__c));
- ++__ret;
}
}
return __ret;
if (__ret < __n)
{
- int_type __c = traits_type::to_int_type(*__s);
- int_type __overfc = this->overflow(__c);
- if (traits_type::eq_int_type(__overfc, traits_type::eof()))
+ int_type __c = this->overflow(traits_type::to_int_type(*__s));
+ if (__c != traits_type::eof())
+ {
+ ++__ret;
+ ++__s;
+ }
+ else
break;
- ++__ret;
- ++__s;
}
}
return __ret;
// NB: std_iostream.h creates the four standard files with
// NULL buffers. At this point, we swap out these placeholder
// objects for the properly-constructed ones
- _M_cout = new filebuf(1, "stdout", ios_base::out);
- _M_cin = new filebuf(0, "stdin", ios_base::in);
- _M_cerr = new filebuf(2, "stderr", ios_base::out);
+ _M_cout = new filebuf(stdout, ios_base::out);
+ _M_cin = new filebuf(stdin, ios_base::in);
+ _M_cerr = new filebuf(stderr, ios_base::out);
new (&cout) ostream(_M_cout);
new (&cin) istream(_M_cin);
new (&cerr) ostream(_M_cerr);
cerr.flags(ios_base::unitbuf);
#ifdef _GLIBCPP_USE_WCHAR_T
- _M_wcout = new wfilebuf(1, "stdout", ios_base::out);
- _M_wcin = new wfilebuf(0, "stdin", ios_base::in);
- _M_wcerr = new wfilebuf(2, "stderr", ios_base::out);
+ _M_wcout = new wfilebuf(stdout, ios_base::out);
+ _M_wcin = new wfilebuf(stdin, ios_base::in);
+ _M_wcerr = new wfilebuf(stderr, ios_base::out);
new (&wcout) wostream(_M_wcout);
new (&wcin) wistream(_M_wcin);
new (&wcerr) wostream(_M_wcerr);
int close_num;
// read (ext)
- int fd = open(name_01, O_RDONLY);
- VERIFY( fd >= 0 );
-
+ FILE* f2 = fopen(name_01, "r");
+ VERIFY( f2 != NULL );
{
- std::filebuf fb(fd, "double_read", std::ios_base::in);
+ std::filebuf fb(f2, std::ios_base::in);
}
-
- close_num = close(fd);
+ close_num = fclose(f2);
VERIFY( close_num == 0 );
// read (standard)
FILE* f = fopen(name_01, "r");
VERIFY( f != NULL );
-
{
std::ifstream ifstream1(name_01);
VERIFY( ifstream1.is_open() );
std::ios_base::iostate st01 = ifstream1.rdstate();
VERIFY( st01 == std::ios_base::goodbit );
}
-
close_num = fclose(f);
VERIFY( close_num == 0 );
test01()
{
std::ios_base::sync_with_stdio();
-
std::freopen("ios_base_members_static-1.txt", "w", stdout);
for (int i = 0; i < 2; i++)
{
std::printf("1");
std::cout << "2";
- std::putc('3', stdout); // std::stdout doesn't work here
+ std::putc('3', stdout);
std::cout << '4';
std::fputs("5", stdout);
std::cout << 6;
std::putchar('7');
std::cout << 8 << '9';
- if (i)
- std::printf ("0\n");
- else
- std::cout << "0" << std::endl;
+ std::printf("0\n");
}
}