This is the mail archive of the
newlib@sourceware.org
mailing list for the newlib project.
Re: Buglet in fseek?
Corinna Vinschen wrote:
On Feb 20 11:44, Jeff Johnston wrote:
Regarding your other note, we could make my initial solution simpler.
fflush() on a read-only stream sets the _SNPT flag on and fseek() clears
it appropriately after doing the lseek. This solves the problem and
doesn't care about what is done in-between. If you fflush() a read-only
stream, then the next fseek()/rewind() you do will be unoptimized. I
think that is fair.
Yep, that sounds good to me.
Thanks,
Corinna
Alright, I have checked in the attached patch. I debugged the two
scenarios to verify it was optimizing without the flush and not
optimizing with the flush.
-- Jeff J.
Index: ChangeLog
===================================================================
RCS file: /cvs/src/src/newlib/ChangeLog,v
retrieving revision 1.872
diff -u -p -r1.872 ChangeLog
--- ChangeLog 16 Feb 2006 21:25:44 -0000 1.872
+++ ChangeLog 20 Feb 2006 23:23:10 -0000
@@ -1,3 +1,10 @@
+2006-02-20 Jeff Johnston <jjohnstn@redhat.com>
+
+ * libc/stdio/fflush.c (fflush): For an fflush on a read-only
+ stream, turn off fseek/rewind optimization as per POSIX/SUSv3.
+ * libc/stdio/fseek.c (_fseek_r): After a successful unoptimized
+ seek, turn off the __SNPT no-optimization flag.
+
2006-02-16 Jeff Johnston <jjohnstn@redhat.com>
* libc/sys/linux/aio.c: Define _GNU_SOURCE so struct aioinit
Index: libc/stdio/fflush.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/fflush.c,v
retrieving revision 1.5
diff -u -p -r1.5 fflush.c
--- libc/stdio/fflush.c 8 Feb 2005 01:33:16 -0000 1.5
+++ libc/stdio/fflush.c 20 Feb 2006 23:23:10 -0000
@@ -72,8 +72,18 @@ _DEFUN(fflush, (fp),
_flockfile (fp);
t = fp->_flags;
- if ((t & __SWR) == 0 || (p = fp->_bf._base) == NULL)
+ if ((t & __SWR) == 0)
{
+ /* For a read stream, an fflush causes the next seek to be
+ unoptimized (i.e. forces a system-level seek). This conforms
+ to the POSIX and SUSv3 standards. */
+ fp->_flags |= __SNPT;
+ _funlockfile (fp);
+ return 0;
+ }
+ if ((p = fp->_bf._base) == NULL)
+ {
+ /* Nothing to flush. */
_funlockfile (fp);
return 0;
}
Index: libc/stdio/fseek.c
===================================================================
RCS file: /cvs/src/src/newlib/libc/stdio/fseek.c,v
retrieving revision 1.11
diff -u -p -r1.11 fseek.c
--- libc/stdio/fseek.c 8 Feb 2005 01:33:16 -0000 1.11
+++ libc/stdio/fseek.c 20 Feb 2006 23:23:10 -0000
@@ -359,6 +359,13 @@ dumb:
fp->_r = 0;
/* fp->_w = 0; *//* unnecessary (I think...) */
fp->_flags &= ~__SEOF;
+ /* Reset no-optimization flag after successful seek. The
+ no-optimization flag may be set in the case of a read
+ stream that is flushed which by POSIX/SUSv3 standards,
+ means that a corresponding seek must not optimize. The
+ optimization is then allowed if no subsequent flush
+ is performed. */
+ fp->_flags &= ~__SNPT;
_funlockfile (fp);
return 0;
}