Fwd: stdio bug

Jeff Johnston jjohnstn@redhat.com
Tue Sep 12 22:55:00 GMT 2006


Eric Blake wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> Originally reported to cygwin, but I think this is a newlib bug.  I
> noticed that fflush sets __SNPT when the file needs an lseek before the
> next read or write; I think that making fclose perform the lseek after
> fflush if __SNPT is set will resolve the situation.  But I haven't had
> time to test a patch along these lines yet.
> 

A bit of a sore-point, but I would like to reiterate: "newlib is not 
POSIX-compliant".  If you go through the POSIX standard, you will find 
quite a few things that newlib doesn't comply with.  That said, newlib 
does not have a bug, but there is a POSIX feature missing that Cygwin 
needs to have implemented.

The POSIX read and write functionality you think is there, actually 
isn't.  Currently, only fseek is looking at the SNPT flag to determine 
if it has to do an lseek instead of using the buffer.  This was added as 
part of a fix for a Cygwin SUSV3-compliance issue: 
http://sourceware.org/ml/newlib/2006/msg00100.html

I think a reasonable alternative would be to first have fflush empty the 
read buffer and to perform the lseek then and there if the current 
buffer is not empty or exhausted.  Any subsequent read would comply with 
the POSIX behavior and close/read logic wouldn't need any changing. 
Multiple fflushing a read file wouldn't result in multiple lseeks since 
the buffer would be cleared after the first call.  Would do you think?

-- Jeff J.

> - -------- Original Message --------
> Subject: stdio bug
> Date: Thu, 07 Sep 2006 21:24:33 +0000 (UTC)
> From: Eric Blake
> To: cygwin
> 
> POSIX requires "When a standard utility reads a seekable input file and
> terminates without an error before it reaches end-of-file, the utility
> shall ensure that the file offset in the open file description is properly
> positioned just past the last byte processed by the utility."
> 
> For an example, POSIX requires these two commands to give the same results:
> $ echo 1 2 3 | tr ' ' '\n' > file
> $ tail -n +2 file
> 2
> 3
> $ (sed -n 1q; cat) < file
> 2
> 3
> 
> On cygwin, this isn't happening:
> 
> $ (sed -n 1q; cat) < file
> $
> 
> But on Solaris, it is:
> 
> $ (truss sed -n 1q; cat) < file 2>&1 | tail
> fstat64(0, 0xFFBEED40)                          = 0
> brk(0x00042100)                                 = 0
> brk(0x00044100)                                 = 0
> read(0, " 1\n 2\n 3\n", 8192)                   = 6
> close(1)                                        = 0
> close(2)                                        = 0
> llseek(0, 0xFFFFFFFFFFFFFFFC, SEEK_CUR)         = 2
> _exit(0)
> 2
> 3
> 
> Notice the llseek(0,-4,SEEK_CUR) just before _exit, which restored the
> file pointer back to the last character consumed, so that cat could then
> start up from the right location.
> 
> I don't know whether a fix to this would lie in fclose() (making sure that
> on input streams, the position of the underlying fd is restored when
> discarding buffered data), or somewhere else, but it would be nice to see
> this fixed.  And it seems like the bug is in cygwin, not sed, since it is
> the same version of GNU sed on both machines.
> 
> - --
> Eric Blake
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.2.1 (Cygwin)
> Comment: Public key at home.comcast.net/~ericblake/eblake.gpg
> Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
> 
> iD8DBQFFBWXF84KuGfSFAYARAqzuAJ4lKjrDRlSy+Fij27uvCFSYls2khwCgjM5C
> MQh5DXfxsVnyNBdfry2SX4Y=
> =8IV6
> -----END PGP SIGNATURE-----



More information about the Newlib mailing list