This is the mail archive of the
libc-alpha@sources.redhat.com
mailing list for the glibc project.
_IO_fwide problem for GLIBC_2.0 compat
- From: Gwenole Beauchesne <gbeauchesne at mandrakesoft dot com>
- To: libc-alpha at sources dot redhat dot com
- Date: Fri, 22 Aug 2003 20:30:21 +0200 (CEST)
- Subject: _IO_fwide problem for GLIBC_2.0 compat
Hi,
The following patch exhausted a problem in libio:
2003-05-06 Ulrich Drepper <drepper@redhat.com>
* libio/oldiofdopen.c (_IO_old_fdopen): Use _IO_old_init not
_IO_init.
* libio/oldiofopen.c (_IO_old_fopen): Likewise.
* libio/libioP.h: Declare _IO_old_init.
* libio/genops.c (_IO_no_init): Split in two. New function
_IO_old_init.
I believe this was done because _IO_old_fopen() allocates a struct with a
shortened version of _IO_FILE, i.e. without the _mode field. It turns out
that in the past, assuming _IO_init() got an fp pointing to a large enough
allocated area, fp->_mode was -1. That is, libio.h (_IO_fwide) would
immediately return it when called from seekoff (_IO_seekoff_unlocked)
for example, thusly not even checking for _IO_have_wbackup().
Nowadays, we may have fp->_mode with non NULL garbage (e.g. 1) and
_IO_seekoff_unlocked() is trying to check for a backup buffer through
garbage'd fp->_wide_data.
An example of this bug can be found at:
<ftp://ftp.netraverse.com/pub/glibc-bug/>
I had workarounded as follows but this cannot be right either:
--- glibc-2.3.2/libio/ioseekoff.c.libio-compat2 2003-08-22 15:46:31.000000000 +0200
+++ glibc-2.3.2/libio/ioseekoff.c 2003-08-22 17:30:04.000000000 +0200
@@ -53,7 +53,12 @@ _IO_seekoff_unlocked (fp, offset, dir, m
callback may not know to do the right thing about it.
This may be over-kill, but it'll do for now. TODO */
if (mode != 0 && ((_IO_fwide (fp, 0) < 0 && _IO_have_backup (fp))
- || (_IO_fwide (fp, 0) > 0 && _IO_have_wbackup (fp))))
+#if defined SHARED && defined _LIBC \
+ && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_1)
+ || (__builtin_expect (&_IO_stdin_used != NULL, 1)
+ && (_IO_fwide (fp, 0) > 0 && _IO_have_wbackup (fp)))
+#endif
+ ))
{
if (dir == _IO_seek_cur && _IO_in_backup (fp))
{