-----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 [EMAIL PROTECTED] -----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-----