bug-gnulib
[Top][All Lists]
Advanced

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

Re: rationale for closein


From: Eric Blake
Subject: Re: rationale for closein
Date: Mon, 18 Jun 2012 20:17:25 -0600
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:13.0) Gecko/20120605 Thunderbird/13.0

On 06/18/2012 06:01 PM, Rich Felker wrote:

> 
> If the "closeout" approach works best for coreutils, that's the
> business of the coreutils' maintainers, not my business. However, as I
> discussed on the musl list, I think it's bad design, and I would
> highly recommend other projects not follow it.

And that's where I disagree - the POSIX folks _specifically_ recommend
the closeout approach of an atexit() handler:

http://austingroupbugs.net/view.php?id=555

"Since after the call to fclose() any use of stream results in undefined
behavior, fclose() should not be used on stdin, stdout, or stderr except
immediately before process termination (see XBD 3.297 on page 81), so as
to avoid triggering undefined behavior in other standard interfaces that
rely on these streams. If there are any atexit() handlers registered by
the application, such a call to fclose() should not occur until the last
handler is finishing. Once fclose() has been used to close stdin,
stdout, or stderr, there is no standard way to reopen any of these streams."

> Conceptually, you're
> turning something that's a local variable (stdout is global, but if
> it's only used from one point as a generic FILE standing in for
> something that would otherwise have been obtained by fopen, it's
> conceptually local) into a global, and thereby losing the _local_
> information of whether it was used in the first place, which has to be
> recovered with the non-portable __fpending.

But our argument is that __fpending (well, 'fpending') _should_ be
portable, and I am in the process of proposing it for standardization in
the next version of POSIX because it is so useful.

> 
> If on the other hand programs just handle stdout as "yet another
> FILE", the same code that checks for write errors and reports failure
> for explicitly-opened files would also check and report write errors
> on stdout. It's not longer a special-case. And special-cases are where
> errors like to hide.

Any program that treats stdout as just like any other file risks closing
stdout too early, and then causing undefined behavior in the rest of the
program when some other standard interface accidentally ends up using fd
1.  The atexit() handler is the easiest way to guarantee that things are
closed properly on all normal exit paths.

> 
>> 'closein' is similar - an attempt to fix an issue that affects many programs,
>> once and for all. By Eric Blake.
> 
> I think closein is just a no-op for conformant implementations. exit
> implicitly closes all streams, including stdin,

But the implicit close by exit(), while properly repositioning stdin (on
working implementations; glibc is broken but I fixed cygwin to be
working), has the drawback of silently eating errors if something went
wrong.  If you WANT to detect read errors, and consolidate the error
detection into a single ferror() location rather than littering the rest
of your code with harder-to-maintain checks, then closein is the way to
go.  If you don't want to detect read errors in a central location, then
yes, avoiding the use of the closein module should have no effect on a
compliant environment; but it is still necessary to work around broken
environments such as glibc.

> Incidentally, I suspect musl is _not_ currently handling this case
> correctly. Does gnulib have some tests that assert the required
> behavior, which I could use to test the current behavior and any
> efforts to fix it if it's wrong?

tests/test-closein.{c,sh}

are sufficient to test the closein module; if you comment out the
atexit() call, it will be sufficient to demonstrate that glibc leaves
stdin at the wrong file offset on exit(); it is also sufficient to
demonstrate that even with a compliant exit(), the implicit close of
exit() eats errors and does not affect error status, whereas the use of
the closein module _does_ detect read errors at a central location.

-- 
Eric Blake   address@hidden    +1-919-301-3266
Libvirt virtualization library http://libvirt.org



Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

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