[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: fflush after ungetc
From: |
Eric Blake |
Subject: |
Re: fflush after ungetc |
Date: |
Fri, 7 Mar 2008 03:41:16 +0000 (UTC) |
User-agent: |
Loom/3.14 (http://gmane.org/) |
Bruno Haible <bruno <at> clisp.org> writes:
>
> Eric Blake wrote:
> > Newlib has two bugs - first, fflush is failing to discard ungetc data when
> > changing the underlying fd offset.
>
> This bug is common to all BSD and AT&T Unix derived implementations. For BSD
> systems, I'm committing this fix. For AT&T Unix derived implementations, I
> don't see an easy fix.
I'm not sure I agree with your patch - I'm starting to waffle on what POSIX
requires. Maybe it's worth asking the Austin Group after all?
But even if we keep your patch unchanged in semantics, it has some nits:
> + /* Clear the ungetc buffer.
> +
> + This is needed before fetching the file-position indicator, because
> + 1) The file position indicator is incremented by fgetc() and
decremented
> + by ungetc():
> + <http://www.opengroup.org/susv3/functions/fgetc.html>
> + "The file-position indicator is decremented by each successful
> + call to ungetc()..."
> + <http://www.opengroup.org/susv3/functions/ungetc.html>
> + "... the fgetc() function shall ... advance the associated file
> + position indicator for the stream ..."
Swapped comments.
> @code{fflush} on an input stream changes the position of the stream to the
> end of the previous buffer, on some platforms: mingw.
> + @item
> + @code{fflush} on an input stream right after @code{ungetc} does not discard
> + the @code{ungetc} buffer, on some platforms:
> + MacOS X 10.3, FreeBSD 6.0, NetBSD 3.0, OpenBSD 3.8, Cygwin.
> + Cygwin.
> @end itemize
Cygwin listed twice. But be aware that there was a change in cygwin behavior
from 1.5.25-10 to 1.5.25-11, due to this thread.
Now, on to my waffling:
> /* Check that fflush after a non-backup ungetc() call discards the ungetc
> buffer. This is mandated by POSIX
> <http://www.opengroup.org/susv3/functions/ungetc.html>:
> "The value of the file-position indicator for the stream after
> reading or discarding all pushed-back bytes shall be the same
> as it was before the bytes were pushed back." */
fflush neither reads nor discards pushed-back bytes (ungetc states that only
fseek, fsetpos, and rewind discard bytes).
> /* Here the file-position indicator must be 2. */
>
> c = ungetc ('@', stdin);
> ASSERT (c == '@');
>
> fflush (stdin);
>
> /* Here the file-position indicator must be 2 again. */
I'm not sure I like these semantics. I would almost rather have the file-
position indicator be 1 at this point, but with fseek(stdin,0,SEEK_CUR)
resetting it to 2 (since fseek discards the ungetc data).
>
> c = fgetc (stdin);
> ASSERT (c == '/');
But then I'm not sure whether this means that this read would result in '!'
(the original byte at position 1 - HP-UX 11 and cygwin 1.5.25-11 behavior), '@'
(the pushed back byte - MacOS X and glibc pipe behavior), or '/' (the byte at
position 2 - glibc seek behavior).
I guess the reason that I want position 1, not 2, is that when you ungetc with
what you just read (rather than with arbitrary data), you are stating that you
want the next process in the pipeline that uses the underlying file description
to consume that byte because you didn't want it after all. But since ungetc is
not allowed to change the underlying file contents, if you push back something
other than what you read before going on to the next process, the next process
cannot read the modified byte (MacOS). I guess it boils down to whether the
next process should reread the original byte (HP-UX) or assume that you
consumed it after all by pushing random data (glibc seek).
ungetc is just a portability pitfall - maybe we're just better off documenting
that portable programs never call more than one ungetc on a stream, and never
with a byte different than what was read (even though this is more restrictive
than what C99 guarantees); although this still doesn't fix the HP-UX pipe bug
for not even allowing one byte of ungetc.
--
Eric Blake
- Re: new module 'freadseek', (continued)
- Message not available
- Re: fflush after ungetc, Eric Blake, 2008/03/26
- Re: fflush after ungetc, Bruno Haible, 2008/03/06
- Re: fflush after ungetc,
Eric Blake <=
- Re: fflush after ungetc, Bruno Haible, 2008/03/09
- Re: fflush after ungetc, Eric Blake, 2008/03/29
- Re: fflush after ungetc, Eric Blake, 2008/03/29
- Re: fflush after ungetc, Bruno Haible, 2008/03/29
- Re: fflush after ungetc, Eric Blake, 2008/03/29
- Re: freadseek, Bruno Haible, 2008/03/30
- Re: fflush after ungetc, Bruno Haible, 2008/03/30
- Re: Cygwin ftell bug, Bruno Haible, 2008/03/06