This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: Plea for clarification on bz #12724
[adding bug-gnulib]
On 07/27/2011 09:31 AM, Csaba Henk wrote:
Hi,
Bugzilla entry #12724 proposes a (by now committed) change
to fclose(3) behavior based on the following citation from
POSIX.1-2008:
"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 closed."
There seems to be an ambiguous corner case, in which case
the behavior adopted is not necessarily wrong, but seems
to be not thought over carefully (see below on the coverage
of the test programs).
That text is outdated. Here's the latest POSIX wording,
http://austingroupbugs.net/view.php?id=87#c838
| At page 805 line 26801 section fclose, change:
|
| 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 closed.
|
| to:
|
| the file offset of the underlying open file description shall be
| set to the file position of the stream.
The text speaks of "_the_ last one [byte] read from or written to
the stream". That's a definite article, thus it presupposes existence.
So, as I interpret, no definitive statement is here about the case
when there was no read or write done on the stream during its lifetime.
Notice that the new wording does not mention the last byte read at all,
but rather focuses solely on stream position.
- Is my interpretation correct?
- If not, what rationale is there to make a choice?
- If yes, what practical arguments are there for chosen behavior?
glibc should strive to match the Solaris behavior.
assert(lseek(fd, 4, SEEK_SET) == 4);
assert (fclose (f) == 0);
errno = 0;
assert (lseek (fd2, 0, SEEK_CUR) == -1);
assert (errno == EBADF);
assert (lseek (fd, 0, SEEK_CUR) == 1);
That's a bug in your test program. The latest POSIX wording requires
the offset of fd to be 4 (because the fclose changed the offset of fd2
to be 4). Once you fix that line of code (in both places, read and
write streams), then Solaris passes once again, which goes to prove that
glibc still has a bug in this area.
- Ruby 1.8.7 build fails with glibc>= 2.14 due to the
chosen no-I/O-fclose behavior, see
http://redmine.ruby-lang.org/issues/5108
They keep around a duplicated file object
to ensure that the original stdio (which might be
redirected during the program run) can be restored.
Even if that part of the code is not used, at GC time
the duplicate is destroyed, implying an fclose() and
an unexpected repositioning of stdout.
I don't know if ruby also has a bug, or if fixing glibc to properly obey
POSIX semantics where fclose() implies lseek() of the underlying fd will
clear up the ruby problem.
Meanwhile, I need to enhance the gnulib testsuite for fclose to test
this additional compliance point, and work around the glibc 2.14
behavior while waiting for a fixed glibc.
--
Eric Blake eblake@redhat.com +1-801-349-2682
Libvirt virtualization library http://libvirt.org