bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Plea for clarification on bz #12724


From: Eric Blake
Subject: Re: Plea for clarification on bz #12724
Date: Thu, 28 Jul 2011 10:46:47 -0600
User-agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.18) Gecko/20110621 Fedora/3.1.11-1.fc14 Lightning/1.0b3pre Mnenhy/0.8.3 Thunderbird/3.1.11

On 07/28/2011 07:30 AM, Eric Blake wrote:
f = fdopen (fd2, "w");
assert (f);
+ printf("%ld\n", ftell(f));

So far, so good. fdopen() is required to set the stream position to the
same as the underlying fd position, so this should always print 1.

assert(lseek(fd, 4, SEEK_SET) == 4);
+ printf("%ld\n", ftell(f));

Undefined behavior. POSIX states:

The result of function calls involving any one handle (the "active
handle") is defined elsewhere in this volume of POSIX.1-2008, but if
two or more handles are used, and any one of them is a stream, the
application shall ensure that their actions are coordinated as
described below. If this is not done, the result is undefined.


http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_05


Your code has two handles (fd and f), you are starting with fd as the
active handle and did a reposition, then switched to an action on f.


The POSIX wording for fclose() effectively requires an fflush(), and
since fflush() is one of the functions that resync's the stream position
back to the fd position as modified by the first handle, before making f
the active handle, I still stand by my analysis that at this point in
the program, the offset of the file description should remain at 4, and
not be reset to 1 (that is, since the transition from the first handle
which set the offset to 4 to the second handle which used fclose() is
clean, the action on the second handle must not corrupt the fd position
back to 1 merely because the FILE* position had not been advanced from
1). Solaris behavior is correct, glibc behavior is buggy.

This topic came up again in today's Austin Group meeting, reaffirming that Solaris behavior is correct and glibc 2.14 behavior, while fixing one aspect of fclose, caused an an unintentional regression in another aspect when compared to 2.13 behavior:

http://austingroupbugs.net/view.php?id=480
http://austingroupbugs.net/view.php?id=87#c895

The latest wording is that with fclose():

the file offset of the underlying open file description shall be set to the file position of the stream if the stream is the active handle to the underlying file description.

Rereading section 2.5.1 tells you when a stream can become the active handle to an underlying file description - only when the previous active handle has gotten to a sane state (either because the previous handle was an fd, or because it was a stream but was unbuffered, at eof, or just flushed), and the new handle does I/O after either ensuring that the old handle did no additional lseek/fseek or the new handle starts I/O with an explicit fseek.

That is, fclose() should _not_ call lseek() to the stream position unless the stream has done any I/O or fseek() which would qualify as making the stream an active handle, such that the stream position has a reason to be reflected back into the file description position.

When dealing with multiple handles to a file description, then you must
ensure that you can properly transition from one active handle to
another. As long as the active handle transition rules are defined, then
yes, a file offset change will be observable as an implicit change in
the file position. As soon as the active handle transition rules are
broken (such as calling ftell() without an intervening fflush()), then

This should have read:
such as calling ftell() without an intervening fseek()

behavior is undefined.

--
Eric Blake   address@hidden    +1-801-349-2682
Libvirt virtualization library http://libvirt.org



reply via email to

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