Commit 95dca20c by Paolo Carlini Committed by Paolo Carlini

re PR libstdc++/7744 (streambuf::in_avail() always returns 0 (zero) for cin input stream)

2003-03-09  Paolo Carlini  <pcarlini@unitus.it>
	    Nathan Myers  <ncm@cantrip.org>

	PR libstdc++/7744
	* config/io/basic_file_stdio.h (__basic_file<>::xsgetn, xsputn,
	seekoff, seekpos): Add a boolean parameter __stdio.
	* config/io/basic_file_stdio.cc (__basic_file<>::xsgetn, xsputn,
	seekoff, seekpos): If __stdio == true, use fread (fwrite, fseek/ftell,
	fseek/ftell, respectively), otherwise read (write, lseek, lseek,
	respectively).
	* include/bits/fstream.tcc (basic_filebuf<>::_M_convert_to_external,
	_M_really_overflow, seekoff): Use the boolean parameter in the calls.
	* include/std/std_fstream.h (sync): Likewise.
	* src/fstream.cc (basic_filebuf<>::_M_underflow_common): Likewise.
	* src/ios.cc (ios_base::Init::_S_ios_create(bool)): Revert libstdc++/8399
	commit involving isatty(0).
	* acinclude.m4 (GLIBCPP_CHECK_UNISTD_DECL_AND_LINKAGE_1): Remove.
        (GLIBCPP_CHECK_UNISTD_SUPPORT): Remove
  	* configure.in: Remove call.
	* aclocal.m4: Regenerate.
       	* config.h.in: Regenerate.
        * configure: Regenerate.
	* testsuite/27_io/narrow_stream_objects.cc (test11): Add.

Co-Authored-By: Nathan Myers <ncm@cantrip.org>

From-SVN: r64051
parent f7b3ab8a
2003-03-09 Paolo Carlini <pcarlini@unitus.it>
Nathan Myers <ncm@cantrip.org>
PR libstdc++/7744
* config/io/basic_file_stdio.h (__basic_file<>::xsgetn, xsputn,
seekoff, seekpos): Add a boolean parameter __stdio.
* config/io/basic_file_stdio.cc (__basic_file<>::xsgetn, xsputn,
seekoff, seekpos): If __stdio == true, use fread (fwrite, fseek/ftell,
fseek/ftell, respectively), otherwise read (write, lseek, lseek,
respectively).
* include/bits/fstream.tcc (basic_filebuf<>::_M_convert_to_external,
_M_really_overflow, seekoff): Use the boolean parameter in the calls.
* include/std/std_fstream.h (sync): Likewise.
* src/fstream.cc (basic_filebuf<>::_M_underflow_common): Likewise.
* src/ios.cc (ios_base::Init::_S_ios_create(bool)): Revert libstdc++/8399
commit involving isatty(0).
* acinclude.m4 (GLIBCPP_CHECK_UNISTD_DECL_AND_LINKAGE_1): Remove.
(GLIBCPP_CHECK_UNISTD_SUPPORT): Remove
* configure.in: Remove call.
* aclocal.m4: Regenerate.
* config.h.in: Regenerate.
* configure: Regenerate.
* testsuite/27_io/narrow_stream_objects.cc (test11): Add.
2003-03-09 Paolo Carlini <pcarlini@unitus.it>
PR libstdc++/9988
* include/bits/fstream.tcc (overflow): don't write EOF to file.
......
......@@ -591,34 +591,6 @@ AC_DEFUN(GLIBCPP_CHECK_STDLIB_DECL_AND_LINKAGE_3, [
])
dnl
dnl Check to see if the (unistd function) argument passed is
dnl 1) declared when using the c++ compiler
dnl 2) has "C" linkage
dnl
dnl argument 1 is name of function to check
dnl
dnl ASSUMES argument is a function with ONE parameter
dnl
dnl GLIBCPP_CHECK_UNISTD_DECL_AND_LINKAGE_1
AC_DEFUN(GLIBCPP_CHECK_UNISTD_DECL_AND_LINKAGE_1, [
AC_MSG_CHECKING([for $1 declaration])
if test x${glibcpp_cv_func_$1_use+set} != xset; then
AC_CACHE_VAL(glibcpp_cv_func_$1_use, [
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
AC_TRY_COMPILE([#include <unistd.h>],
[ $1(0);],
[glibcpp_cv_func_$1_use=yes], [glibcpp_cv_func_$1_use=no])
AC_LANG_RESTORE
])
fi
AC_MSG_RESULT($glibcpp_cv_func_$1_use)
if test x$glibcpp_cv_func_$1_use = x"yes"; then
AC_CHECK_FUNCS($1)
fi
])
dnl
dnl Because the builtins are picky picky picky about the arguments they take,
dnl do an explict linkage tests here.
dnl Check to see if the (math function) argument passed is
......@@ -753,26 +725,6 @@ AC_DEFUN(GLIBCPP_CHECK_STDLIB_SUPPORT, [
])
dnl
dnl Check to see what the underlying c library is like
dnl These checks need to do two things:
dnl 1) make sure the name is declared when using the c++ compiler
dnl 2) make sure the name has "C" linkage
dnl This might seem like overkill but experience has shown that it's not...
dnl
dnl Define HAVE_ISATTY if "isatty" is declared and links
dnl
dnl GLIBCPP_CHECK_UNISTD_SUPPORT
AC_DEFUN(GLIBCPP_CHECK_UNISTD_SUPPORT, [
ac_test_CXXFLAGS="${CXXFLAGS+set}"
ac_save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS='-fno-builtins -D_GNU_SOURCE'
GLIBCPP_CHECK_UNISTD_DECL_AND_LINKAGE_1(isatty)
CXXFLAGS="$ac_save_CXXFLAGS"
])
dnl
dnl Check to see what the underlying c library or math library is like.
dnl These checks need to do two things:
dnl 1) make sure the name is declared when using the c++ compiler
......
dnl aclocal.m4 generated automatically by aclocal 1.4-p5
dnl aclocal.m4 generated automatically by aclocal 1.4-p6
dnl Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
......@@ -603,34 +603,6 @@ AC_DEFUN(GLIBCPP_CHECK_STDLIB_DECL_AND_LINKAGE_3, [
])
dnl
dnl Check to see if the (unistd function) argument passed is
dnl 1) declared when using the c++ compiler
dnl 2) has "C" linkage
dnl
dnl argument 1 is name of function to check
dnl
dnl ASSUMES argument is a function with ONE parameter
dnl
dnl GLIBCPP_CHECK_UNISTD_DECL_AND_LINKAGE_1
AC_DEFUN(GLIBCPP_CHECK_UNISTD_DECL_AND_LINKAGE_1, [
AC_MSG_CHECKING([for $1 declaration])
if test x${glibcpp_cv_func_$1_use+set} != xset; then
AC_CACHE_VAL(glibcpp_cv_func_$1_use, [
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
AC_TRY_COMPILE([#include <unistd.h>],
[ $1(0);],
[glibcpp_cv_func_$1_use=yes], [glibcpp_cv_func_$1_use=no])
AC_LANG_RESTORE
])
fi
AC_MSG_RESULT($glibcpp_cv_func_$1_use)
if test x$glibcpp_cv_func_$1_use = x"yes"; then
AC_CHECK_FUNCS($1)
fi
])
dnl
dnl Because the builtins are picky picky picky about the arguments they take,
dnl do an explict linkage tests here.
dnl Check to see if the (math function) argument passed is
......@@ -765,26 +737,6 @@ AC_DEFUN(GLIBCPP_CHECK_STDLIB_SUPPORT, [
])
dnl
dnl Check to see what the underlying c library is like
dnl These checks need to do two things:
dnl 1) make sure the name is declared when using the c++ compiler
dnl 2) make sure the name has "C" linkage
dnl This might seem like overkill but experience has shown that it's not...
dnl
dnl Define HAVE_ISATTY if "isatty" is declared and links
dnl
dnl GLIBCPP_CHECK_UNISTD_SUPPORT
AC_DEFUN(GLIBCPP_CHECK_UNISTD_SUPPORT, [
ac_test_CXXFLAGS="${CXXFLAGS+set}"
ac_save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS='-fno-builtins -D_GNU_SOURCE'
GLIBCPP_CHECK_UNISTD_DECL_AND_LINKAGE_1(isatty)
CXXFLAGS="$ac_save_CXXFLAGS"
])
dnl
dnl Check to see what the underlying c library or math library is like.
dnl These checks need to do two things:
dnl 1) make sure the name is declared when using the c++ compiler
......@@ -2313,7 +2265,7 @@ AC_MSG_RESULT($enable_symvers)
])
# isc-posix.m4 serial 1 (gettext-0.10.40)
# isc-posix.m4 serial 2 (gettext-0.11.2)
dnl Copyright (C) 1995-2002 Free Software Foundation, Inc.
dnl This file is free software, distributed under the terms of the GNU
dnl General Public License. As a special exception to the GNU General
......@@ -2321,6 +2273,8 @@ dnl Public License, this file may be distributed as part of a program
dnl that contains a configuration script generated by Autoconf, under
dnl the same distribution terms as the rest of that program.
# This file is not needed with autoconf-2.53 and newer. Remove it in 2005.
# This test replaces the one in autoconf.
# Currently this macro should have the same name as the autoconf macro
# because gettext's gettext.m4 (distributed in the automake package)
......@@ -2381,7 +2335,8 @@ dnl Usage:
dnl AM_INIT_AUTOMAKE(package,version, [no-define])
AC_DEFUN([AM_INIT_AUTOMAKE],
[AC_REQUIRE([AC_PROG_INSTALL])
[AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
AC_REQUIRE([AC_PROG_INSTALL])
PACKAGE=[$1]
AC_SUBST(PACKAGE)
VERSION=[$2]
......@@ -2397,13 +2352,42 @@ AC_REQUIRE([AM_SANITY_CHECK])
AC_REQUIRE([AC_ARG_PROGRAM])
dnl FIXME This is truly gross.
missing_dir=`cd $ac_aux_dir && pwd`
AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}, $missing_dir)
AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}, $missing_dir)
AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
AC_REQUIRE([AC_PROG_MAKE_SET])])
# Copyright 2002 Free Software Foundation, Inc.
# This program 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 program 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 program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# AM_AUTOMAKE_VERSION(VERSION)
# ----------------------------
# Automake X.Y traces this macro to ensure aclocal.m4 has been
# generated from the m4 files accompanying Automake X.Y.
AC_DEFUN([AM_AUTOMAKE_VERSION],[am__api_version="1.4"])
# AM_SET_CURRENT_AUTOMAKE_VERSION
# -------------------------------
# Call AM_AUTOMAKE_VERSION so it can be traced.
# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
[AM_AUTOMAKE_VERSION([1.4-p6])])
#
# Check to make sure that the build environment is sane.
#
......
......@@ -461,9 +461,6 @@
/* Define if you have the iconv_open function. */
#undef HAVE_ICONV_OPEN
/* Define if you have the isatty function. */
#undef HAVE_ISATTY
/* Define if you have the isinf function. */
#undef HAVE_ISINF
......
// Wrapper of C-language FILE struct -*- C++ -*-
// Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
// Copyright (C) 2000, 2001, 2002, 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
......@@ -33,6 +33,7 @@
#include <bits/basic_file.h>
#include <fcntl.h>
#include <errno.h>
namespace std
{
......@@ -191,33 +192,69 @@ namespace std
return __retval;
}
// In the next four functions we want to use stdio functions only
// when synced with stdio (_M_buf_size == 1): I/O primitives do not
// block until the asked number of bytes are available.
streamsize
__basic_file<char>::xsgetn(char* __s, streamsize __n)
{ return fread(__s, 1, __n, _M_cfile); }
__basic_file<char>::xsgetn(char* __s, streamsize __n, bool __stdio)
{
if (__stdio)
return fread(__s, 1, __n, _M_cfile);
else
{
streamsize __ret;
do
__ret = read(this->fd(), __s, __n);
while (__ret == -1L && errno == EINTR);
return __ret;
}
}
streamsize
__basic_file<char>::xsputn(const char* __s, streamsize __n)
{ return fwrite(__s, 1, __n, _M_cfile); }
__basic_file<char>::xsputn(const char* __s, streamsize __n, bool __stdio)
{
if (__stdio)
return fwrite(__s, 1, __n, _M_cfile);
else
{
streamsize __ret;
do
__ret = write(this->fd(), __s, __n);
while (__ret == -1L && errno == EINTR);
return __ret;
}
}
streamoff
__basic_file<char>::seekoff(streamoff __off, ios_base::seekdir __way,
ios_base::openmode /*__mode*/)
bool __stdio, ios_base::openmode /*__mode*/)
{
if (!fseek(_M_cfile, __off, __way))
return ftell(_M_cfile);
if (!__stdio)
return lseek(this->fd(), __off, __way);
else
// Fseek failed.
return -1L;
{
if (!fseek(_M_cfile, __off, __way))
return ftell(_M_cfile);
else
// Fseek failed.
return -1L;
}
}
streamoff
__basic_file<char>::seekpos(streamoff __pos, ios_base::openmode /*__mode*/)
__basic_file<char>::seekpos(streamoff __pos, bool __stdio,
ios_base::openmode /*__mode*/)
{
if (!fseek(_M_cfile, __pos, ios_base::beg))
return ftell(_M_cfile);
if (!__stdio)
return lseek(this->fd(), __pos, ios_base::beg);
else
// Fseek failed.
return -1L;
{
if (!fseek(_M_cfile, __pos, ios_base::beg))
return ftell(_M_cfile);
else
// Fseek failed.
return -1L;
}
}
int
......
......@@ -93,17 +93,17 @@ namespace std
~__basic_file();
streamsize
xsputn(const char* __s, streamsize __n);
xsputn(const char* __s, streamsize __n, bool __stdio);
streamsize
xsgetn(char* __s, streamsize __n);
xsgetn(char* __s, streamsize __n, bool __stdio);
streamoff
seekoff(streamoff __off, ios_base::seekdir __way,
seekoff(streamoff __off, ios_base::seekdir __way, bool __stdio,
ios_base::openmode __mode = ios_base::in | ios_base::out);
streamoff
seekpos(streamoff __pos,
seekpos(streamoff __pos, bool __stdio,
ios_base::openmode __mode = ios_base::in | ios_base::out);
int
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -411,7 +411,6 @@ else
GLIBCPP_CHECK_COMPLEX_MATH_SUPPORT
GLIBCPP_CHECK_WCHAR_T_SUPPORT
GLIBCPP_CHECK_STDLIB_SUPPORT
GLIBCPP_CHECK_UNISTD_SUPPORT
AC_LC_MESSAGES
AC_TRY_COMPILE([
......
......@@ -102,7 +102,7 @@ namespace std
// using underflow.
if (__mode & ios_base::in && _M_buf_allocated)
this->underflow();
if ((__mode & ios_base::ate)
&& this->seekoff(0, ios_base::end, __mode) < 0)
{
......@@ -276,10 +276,13 @@ namespace std
{
const locale __loc = this->getloc();
const __codecvt_type& __cvt = use_facet<__codecvt_type>(__loc);
// Sync with stdio.
bool __sync = this->_M_buf_size == 1;
if (__cvt.always_noconv() && __ilen)
{
__elen += _M_file.xsputn(reinterpret_cast<char*>(__ibuf), __ilen);
__elen +=
_M_file.xsputn(reinterpret_cast<char*>(__ibuf), __ilen, __sync);
__plen += __ilen;
}
else
......@@ -309,7 +312,7 @@ namespace std
if (__blen)
{
__elen += _M_file.xsputn(__buf, __blen);
__elen += _M_file.xsputn(__buf, __blen, __sync);
__plen += __blen;
}
......@@ -331,7 +334,7 @@ namespace std
}
if (__rlen)
{
__elen += _M_file.xsputn(__buf, __rlen);
__elen += _M_file.xsputn(__buf, __rlen, __sync);
__plen += __rlen;
}
}
......@@ -346,6 +349,8 @@ namespace std
int_type __ret = traits_type::eof();
bool __testput = this->_M_out_cur && this->_M_out_beg < this->_M_out_lim;
bool __testunbuffered = _M_file.is_open() && !this->_M_buf_size_opt;
// Sync with stdio.
bool __sync = this->_M_buf_size == 1;
if (__testput || __testunbuffered)
{
......@@ -359,7 +364,7 @@ namespace std
if (_M_filepos && _M_filepos != this->_M_out_beg)
{
off_type __off = this->_M_out_beg - _M_filepos;
_M_file.seekoff(__off, ios_base::cur);
_M_file.seekoff(__off, ios_base::cur, __sync);
}
// Convert internal buffer to external representation, output.
......@@ -434,7 +439,9 @@ namespace std
pos_type __ret = pos_type(off_type(-1));
bool __testin = (ios_base::in & this->_M_mode & __mode) != 0;
bool __testout = (ios_base::out & this->_M_mode & __mode) != 0;
// Sync with stdio.
bool __sync = this->_M_buf_size == 1;
// Should probably do has_facet checks here.
int __width = use_facet<__codecvt_type>(this->_M_buf_locale).encoding();
if (__width < 0)
......@@ -468,7 +475,7 @@ namespace std
__computed_off += this->_M_in_cur - _M_filepos;
// Return pos_type(off_type(-1)) in case of failure.
__ret = _M_file.seekoff(__computed_off, __way, __mode);
__ret = _M_file.seekoff(__computed_off, __way, __sync, __mode);
_M_set_indeterminate();
}
// NB: Need to do this in case _M_file in indeterminate
......@@ -476,7 +483,8 @@ namespace std
else
{
pos_type __tmp =
_M_file.seekoff(__off, ios_base::cur, __mode);
_M_file.seekoff(__off, ios_base::cur,
__sync, __mode);
if (__tmp >= 0)
{
// Seek successful.
......
......@@ -314,6 +314,8 @@ namespace std
int __ret = 0;
bool __testput = this->_M_out_cur
&& this->_M_out_beg < this->_M_out_lim;
// Sync with stdio.
bool __sync = this->_M_buf_size == 1;
// Make sure that the internal buffer resyncs its idea of
// the file position with the external file.
......@@ -327,7 +329,7 @@ namespace std
traits_type::eof()))
__ret = -1;
else if (__off)
_M_file.seekoff(__off, ios_base::cur);
_M_file.seekoff(__off, ios_base::cur, __sync);
}
else
_M_file.sync();
......
......@@ -43,6 +43,8 @@ namespace std
int_type __ret = traits_type::eof();
bool __testin = _M_mode & ios_base::in;
bool __testout = _M_mode & ios_base::out;
// Sync with stdio.
bool __sync = _M_buf_size == 1;
if (__testin)
{
......@@ -71,15 +73,16 @@ namespace std
_M_really_overflow();
else if (_M_in_cur != _M_filepos)
_M_file.seekoff(_M_in_cur - _M_filepos,
ios_base::cur, ios_base::in);
ios_base::cur, __sync, ios_base::in);
}
if (__testinit || __testget)
{
streamsize __elen = 0;
streamsize __ilen = 0;
__elen = _M_file.xsgetn(reinterpret_cast<char*>(_M_in_beg),
_M_buf_size);
_M_buf_size, __sync);
__ilen = __elen;
if (0 < __ilen)
......@@ -90,7 +93,7 @@ namespace std
__ret = traits_type::to_int_type(*_M_in_cur);
if (__bump)
_M_in_cur_move(1);
else if (_M_buf_size == 1)
else if (__sync)
{
// If we are synced with stdio, we have to unget the
// character we just read so that the file pointer
......@@ -123,6 +126,8 @@ namespace std
int_type __ret = traits_type::eof();
bool __testin = _M_mode & ios_base::in;
bool __testout = _M_mode & ios_base::out;
// Sync with stdio.
bool __sync = _M_buf_size == 1;
if (__testin)
{
......@@ -151,7 +156,7 @@ namespace std
_M_really_overflow();
else if (_M_in_cur != _M_filepos)
_M_file.seekoff(_M_in_cur - _M_filepos,
ios_base::cur, ios_base::in);
ios_base::cur, __sync, ios_base::in);
}
if (__testinit || __testget)
......@@ -164,13 +169,13 @@ namespace std
if (__cvt.always_noconv())
{
__elen = _M_file.xsgetn(reinterpret_cast<char*>(_M_in_beg),
_M_buf_size);
_M_buf_size, __sync);
__ilen = __elen;
}
else
{
char* __buf = static_cast<char*>(__builtin_alloca(_M_buf_size));
__elen = _M_file.xsgetn(__buf, _M_buf_size);
__elen = _M_file.xsgetn(__buf, _M_buf_size, __sync);
const char* __eend;
char_type* __iend;
......@@ -183,7 +188,7 @@ namespace std
{
// Unwind.
__ilen = 0;
_M_file.seekoff(-__elen, ios_base::cur, ios_base::in);
_M_file.seekoff(-__elen, ios_base::cur, __sync, ios_base::in);
}
}
......@@ -195,7 +200,7 @@ namespace std
__ret = traits_type::to_int_type(*_M_in_cur);
if (__bump)
_M_in_cur_move(1);
else if (_M_buf_size == 1)
else if (__sync)
{
// If we are synced with stdio, we have to unget the
// character we just read so that the file pointer
......
......@@ -38,9 +38,6 @@
#include <fstream>
#include <bits/atomicity.h>
#include <ext/stdio_filebuf.h>
#ifdef _GLIBCPP_HAVE_UNISTD_H
#include <unistd.h>
#endif
namespace __gnu_cxx
{
......@@ -160,12 +157,7 @@ namespace std
ios_base::Init::_S_ios_create(bool __sync)
{
size_t __out_size = __sync ? 0 : static_cast<size_t>(BUFSIZ);
#ifdef _GLIBCPP_HAVE_ISATTY
size_t __in_size =
(__sync || isatty (0)) ? 1 : static_cast<size_t>(BUFSIZ);
#else
size_t __in_size = 1;
#endif
size_t __in_size = __sync ? 1 : static_cast<size_t>(BUFSIZ);
// NB: The file globals.cc creates the four standard files
// with NULL buffers. At this point, we swap out the dummy NULL
......
......@@ -204,6 +204,22 @@ test10()
cout << "_M_gcount: "<< cin.gcount() << endl;
}
// libstdc++/7744
void test11()
{
std::ios::sync_with_stdio(false);
std::cout
<< "\n:: f2() ::\n"
<< "Type in the characters 'abc' and press <ENTER>: ";
std::cin.peek();
std::cout
<< "The number of unread characters should be 4 (a, b, c, \\n): "
<< std::cin.rdbuf()->in_avail()
<< '\n';
}
int
main()
{
......@@ -218,5 +234,6 @@ main()
// test08();
// test09();
// test10();
// test11();
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment