bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: 'fflush' test failure on Cygwin


From: Eric Blake
Subject: Re: 'fflush' test failure on Cygwin
Date: Thu, 12 Apr 2007 20:00:38 -0600
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.10) Gecko/20070221 Thunderbird/1.5.0.10 Mnenhy/0.7.5.666

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

According to Bruno Haible on 4/12/2007 7:30 PM:
> 
> But it's the goal of the 'fflush' module to make this test work, no?

Yes

> 
>> But seeing as how the failure symptom is the same as that of MacOSX,
> 
> Indeed, on MacOS X 10.3.9, the lseek call in test-fflush.c:70 also yields 10,
> not 5.
> 
>> I'm wondering if anyone has better ideas of how to force stdio to reposition
>> the offset of the underlying fd when fflush (or fpurge) followed by fseek
>> is not powerful enough to do the same.  I could always do a raw lseek
>> myself, but that makes me worry that if stdio has read in a buffer, then
>> stdio will be confused because the fd changed behind its back.
> 
> After looking at the MacOS X source files
>    Libc-320.1.3/stdio/FreBSD/fflush.c
>    Libc-320.1.3/stdio/FreBSD/fseek.c
> (from http://developer.apple.com/opensource/ -> Darwin -> MacOS X 10.3.9
> Source -> Libc-320.1.3) for two hours, here's what I think:
> 

Thanks for the advice.  It looks rather similar to newlib prior to my
fflush patches.
http://cygwin.com/cgi-bin/cvsweb.cgi/src/newlib/libc/stdio/?cvsroot=src

> 
> 1) fpurge exists on MacOS X, but only clears the buffer, without changing
>    the file descriptor's position in the kernel. So it needs this change
>    (otherwise the stream's position before the fflush() call is lost):
> 
> *** lib/fflush.c      2007-04-13 00:15:11.000000000 +0200
> --- lib/fflush.c      2007-04-13 02:44:10.000000000 +0200
> ***************
> *** 57,63 ****
>     /* To get here, we must be flushing a seekable input stream, so the
>        semantics of fpurge are now appropriate.  */
>   #if HAVE_FPURGE
> !   result = fpurge (stream);
>   #elif HAVE___FPURGE
>     /* __fpurge has no return value, and on Solaris, we can't even trust
>        errno.  So assume it succeeds.  */
> --- 57,72 ----
>     /* To get here, we must be flushing a seekable input stream, so the
>        semantics of fpurge are now appropriate.  */
>   #if HAVE_FPURGE
> !   {
> !     off_t pos = ftello (stream);
> ! 
> !     result = fpurge (stream);
> !     if (result == 0)
> !       {
> !     if (lseek (fileno (stream), pos, SEEK_SET) == -1)
> !       result = EOF;
> !       }
> !   }
>   #elif HAVE___FPURGE
>     /* __fpurge has no return value, and on Solaris, we can't even trust
>        errno.  So assume it succeeds.  */
> 
> 
> 2) fseek() is heavily optimized: fseeko (fp, pos, SEEK_SET) will position
>    the file descriptor to   pos & ~fp->_blksize  and then read one buffer,
>    [or if   pos   is inside the current buffer, optimize even more: just
>    change some pointers and counters, without accessing the file descriptor],

cygwin 1.5.19 has some of the same optimizations to work around.  In fact,
I think all stdio implementations that drew inspiration from the old BSD
sources have this problem, although the various branches have forked in
different directions since the common code base.

>    unless
>      - fp is not seekable, or
>      - fp is open for writing (__SWR | __SRW), or
>      - fp is unbuffered (__SNBF), or
>      - fp has an unusual block size set through setvbuf (__SNPT).
>    If your fflush or fseek was to invoke setvbuf, it's hard to keep programs
>    working that use setvbuf as well.
> 
>    A solution might be to make a wrapper around fseek() roughly like this:
> 
>      rpl_fseek (...)
>      {
>        if (fp is not open for writing
>            && fp's buffer is empty, like after fpurge)
>          perform just an lseek
>        else
>          fseek (...);
>      }

Wow, I sure bit off a big chunk, trying to make the stdio libraries
correct.  I'm still worried, though, that after using
rpl_fflush/rpl_fseek, will fread/fgetc pick up at the correct character?
I hope not to rewrite the entire stdio.

> 
>    The primitives for "fp is not open for writing" can be written in the
>    same spirit as the 'fseterr' and 'fpending' modules.

It sounds like you are asking for __freading:

http://docs.sun.com/app/docs/doc/806-0627/6j9vhfmre?q=__fpurge&a=view

We probably should provide modules for all of the following useful stdio
functions that the standards developers left out:

__fbufsize
__flbf
__fpending - done
__fpurge
__freadable
__freading
__fsetlocking
__fwritable
__fwriting
__flushlbf

- --
Don't work too hard, make some time for fun as well!

Eric Blake             address@hidden
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (Cygwin)
Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFGHuRG84KuGfSFAYARAuxuAKDC1frmSvuNlWFu8Lw+syhIMjX0YACfej0Q
dXJ9Xpx03XRIruFJr3cbNfE=
=dKXG
-----END PGP SIGNATURE-----




reply via email to

[Prev in Thread] Current Thread [Next in Thread]