bug-gnulib
[Top][All Lists]
Advanced

[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:14:15 +0000 (UTC)
User-agent: Loom/3.14 (http://gmane.org/)

Bruno Haible <bruno <at> clisp.org> writes:

> 
> Eric Blake wrote on Saturday:
> > Newlib has two bugs - first, fflush is failing to discard ungetc data when
> > changing the underlying fd offset.
> 
> Do you know the wording that the newest POSIX has about this?

The ungetc wording is unchanged from POSIX 2001 (or from C99).

The fflush wording adds this paragraph:

"For a stream open for reading, if the file is not already at EOF, and the file 
is one capable of seeking, the file offset of the underlying open file 
description shall be adjusted so that the next operation on the open file 
description deals with the byte after the last one read from or written to the 
stream being flushed."

According to ungetc, only fseek, fsetpos, and rewind can discard ungetc bytes, 
and even then, only if the underlying file is seekable (since they are 
unsuccessful on unseekable files).  My reading is that fflush is NOT a file-
positioning function in this case.

"A successful intervening call (with the stream pointed to by stream) to a file-
positioning function (fseek( ), fsetpos( ), or rewind( )) shall discard any 
pushed-back bytes for the stream... 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."

> On glibc-2.3.6: Different results.
> When reading from the regular file:
> c = '#'
> c = 'i'
> ungetc result = '@'
> c = 'n'
> c = 'c'

I claim this is a glibc bug (gasp!).  fflush should not discard the ungetc 
data, so the third fgetc should have returned '@', and the fourth 'n'.

> When reading from the pipe:
> c = '#'
> c = 'i'
> ungetc result = '@'
> c = '@'
> c = 'n'

Fine.

> 
> On MacOS X: twice
> c = '#'
> c = 'i'
> ungetc result = '@'
> c = '@'
> c = 'n'

Fine.

> 
> On HP-UX 11:
> When reading from the regular file:
> c = '#'
> c = 'i'
> ungetc result = '@'
> c = 'i'
> c = 'n'

Bug - the third fgetc should have read from the ungetc buffer, not the 
underlying file.

> When reading from the pipe:
> c = '#'
> c = 'i'
> ungetc result = '@'
> c = <EOF>
> c = <EOF>

Bug - C99 requires that ALL streams have at least one byte of ungetc space, 
with no limitation on what can go in that buffer.  You only invoke unspecified 
behavior when you use ungetc() multiple times in a row.

> 
> If I understand the comments in lib/fflush.c right, the second half of my
> test is unspecified behaviour, and the first half is specified and exposes
> in MacOS X the same bug as on Cygwin?

By my reading, MacOS X and Cygwin 1.5.25-11 are correct (cygwin 1.5.25-10 and 
earlier are buggy).  But glibc is not.

-- 
Eric Blake






reply via email to

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