This is the mail archive of the
glibc-bugs@sourceware.org
mailing list for the glibc project.
[Bug libc/2074] _IO_new_file_xsputn() in fileops.c not checking for EOF
- From: "jfardo at laurelnetworks dot com" <sourceware-bugzilla at sourceware dot org>
- To: glibc-bugs at sources dot redhat dot com
- Date: 3 Aug 2006 18:54:53 -0000
- Subject: [Bug libc/2074] _IO_new_file_xsputn() in fileops.c not checking for EOF
- References: <20051220202817.2074.jfardo@laurelnetworks.com>
- Reply-to: sourceware-bugzilla at sourceware dot org
------- Additional Comments From jfardo at laurelnetworks dot com 2006-08-03 18:54 -------
(In reply to comment #0)
> In glibc 2.3.4, the function new_do_write() in libio/fileops.c returns an
> unsigned
> value (an _IO_size_t). If the underlying write system call in new_do_write()
> returns EOF (-1), new_do_write() will return 0xffffffff rather than -1.
> The function IO_new_file_xsputn() in libio/fileops.c appears to have
> 2 problems if the call to new_do_write() returns 0xffffffff. Here's
> the specific snippet of code from IO_new_file_xsputn():
> if (do_write)
> {
> count = new_do_write (f, s, do_write);
> to_do -= count;
> if (count < do_write)
> return n - to_do;
> }
> /* Now write out the remainder. Normally, this will fit in the
> buffer, but it's somewhat messier for line-buffered files,
> so we let _IO_default_xsputn handle the general case. */
> if (to_do)
> to_do -= INTUSE(_IO_default_xsputn) (f, s+do_write, to_do);
> }
> return n - to_do;
> If new_do_write() returns 0xffffffff, 'to_do' will actually
> be incremented by 1. Also, since 'count' is an unsigned quantity,
> the if statement 'if (count < do_write)' will evaluate to false,
> and the code will incorrectly fall through to the call to
> IO_default_xsputn().
(In reply to comment #3)
_IO_new_file_xsputn() calls new_do_write() which in turn calls _IO_SYSWRITE().
The call to _IO_SYSWRITE() may return -1 (EOF). When this happens, new_do_write
() returns this value as the 'count'.
I've highlighted this in the following piece of code in fileops.c.
static
int
new_do_write (fp, data, to_do)
_IO_FILE *fp;
const char *data;
_IO_size_t to_do;
{
_IO_size_t count;
if (fp->_flags & _IO_IS_APPENDING)
/* On a system without a proper O_APPEND implementation,
you would need to sys_seek(0, SEEK_END) here, but is
is not needed nor desirable for Unix- or Posix-like systems.
Instead, just indicate that offset (before and after) is
unpredictable. */
fp->_offset = _IO_pos_BAD;
else if (fp->_IO_read_end != fp->_IO_write_base)
{
_IO_off64_t new_pos
= _IO_SYSSEEK (fp, fp->_IO_write_base - fp->_IO_read_end, 1);
if (new_pos == _IO_pos_BAD)
return 0;
fp->_offset = new_pos;
}
********** THIS CALL MAY RETURN -1 ***************
count = _IO_SYSWRITE (fp, data, to_do);
*************************************************
if (fp->_cur_column && count)
fp->_cur_column = INTUSE(_IO_adjust_column) (fp->_cur_column - 1, data,
count) + 1;
_IO_setg (fp, fp->_IO_buf_base, fp->_IO_buf_base, fp->_IO_buf_base);
fp->_IO_write_base = fp->_IO_write_ptr = fp->_IO_buf_base;
fp->_IO_write_end = (fp->_mode <= 0
&& (fp->_flags & (_IO_LINE_BUF+_IO_UNBUFFERED))
? fp->_IO_buf_base : fp->_IO_buf_end);
return count;
}
--
http://sourceware.org/bugzilla/show_bug.cgi?id=2074
------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.