stdio patch
Jeff Johnston
jjohnstn@redhat.com
Thu Dec 14 23:31:00 GMT 2006
Great. Patch checked in.
-- Jeff J.
Eric Blake wrote:
> Jeff, this patch is based on what you sent me privately, plus a typo fix for
> SEEK_SET instead of SEEK_CUR, and the additional fix to keep fp->offset up-to-
> date when __SOFF. With it, I now get the POSIX-mandated behavior on cygwin for:
>
> $ echo 1 2 3 | tr ' ' '\n' > file
> $ (sed -n 1q; cat) < file
> 2
> 3
>
>
> 2006-12-14 Jeff Johnston <jjohnstn@redhat.com>
> and Eric Blake <ebb9@byu.net>
>
> * libc/stdio/fflush.c (fflush): On seekable streams, always flush
> read but unused data.
> * libc/stdio/fclose.c (_fclose_r): Always flush streams, since
> even read streams may have side effects that must happen.
>
> Index: libc/stdio/fclose.c
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/stdio/fclose.c,v
> retrieving revision 1.11
> diff -u -p -r1.11 fclose.c
> --- libc/stdio/fclose.c 26 Sep 2006 21:22:19 -0000 1.11
> +++ libc/stdio/fclose.c 14 Dec 2006 21:22:44 -0000
> @@ -86,7 +86,10 @@ _DEFUN(_fclose_r, (rptr, fp),
> __sfp_lock_release ();
> return (0);
> }
> - r = fp->_flags & __SWR ? fflush (fp) : 0;
> + /* Unconditionally flush to allow special handling for seekable read
> + files to reposition file to last byte processed as opposed to
> + last byte read ahead into the buffer. */
> + r = fflush (fp);
> if (fp->_close != NULL && (*fp->_close) (fp->_cookie) < 0)
> r = EOF;
> if (fp->_flags & __SMBF)
> Index: libc/stdio/fflush.c
> ===================================================================
> RCS file: /cvs/src/src/newlib/libc/stdio/fflush.c,v
> retrieving revision 1.7
> diff -u -p -r1.7 fflush.c
> --- libc/stdio/fflush.c 26 Sep 2006 21:22:19 -0000 1.7
> +++ libc/stdio/fflush.c 14 Dec 2006 21:22:44 -0000
> @@ -1,5 +1,5 @@
> /*
> - * Copyright (c) 1990 The Regents of the University of California.
> + * Copyright (c) 1990, 2006 The Regents of the University of California.
> * All rights reserved.
> *
> * Redistribution and use in source and binary forms are permitted
> @@ -74,10 +74,56 @@ _DEFUN(fflush, (fp),
> t = fp->_flags;
> if ((t & __SWR) == 0)
> {
> + _fpos_t _EXFUN((*seekfn), (_PTR, _fpos_t, int));
> +
> /* 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;
> +
> + /* For a seekable stream with buffered read characters, we will attempt
> + a seek to the current position now. A subsequent read will then get
> + the next byte from the file rather than the buffer. This conforms
> + to the POSIX and SUSv3 standards. Note that the standards allow
> + this seek to be deferred until necessary, but we choose to do it here
> + to make the change simpler, more contained, and less likely
> + to miss a code scenario. */
> + if ((fp->_r > 0 || fp->_ur > 0) && (seekfn = fp->_seek) != NULL)
> + {
> + _fpos_t curoff;
> +
> + /* Get the physical position we are at in the file. */
> + if (fp->_flags & __SOFF)
> + curoff = fp->_offset;
> + else
> + {
> + /* We don't know current physical offset, so ask for it. */
> + curoff = (*seekfn) (fp->_cookie, (_fpos_t) 0, SEEK_CUR);
> + if (curoff == -1L)
> + {
> + _funlockfile (fp);
> + return 0;
> + }
> + }
> + if (fp->_flags & __SRD)
> + {
> + /* Current offset is at end of buffer. Compensate for
> + characters not yet read. */
> + curoff -= fp->_r;
> + if (HASUB (fp))
> + curoff -= fp->_ur;
> + }
> + /* Now physically seek to after byte last read. */
> + if ((*seekfn)(fp->_cookie, curoff, SEEK_SET) != -1)
> + {
> + /* Seek successful. We can clear read buffer now. */
> + fp->_flags &= ~__SNPT;
> + fp->_r = 0;
> + fp->_p = fp->_bf._base;
> + if (fp->_flags & __SOFF)
> + fp->_offset = curoff;
> + }
> + }
> _funlockfile (fp);
> return 0;
> }
>
>
More information about the Newlib
mailing list