-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 According to Bruno Haible on 7/18/2009 1:03 AM: >> calls close_stream (stdout) >> => fclose (stdout) >> detects that pending data was lost, so call error() >> => fflush (stdout) >> >> According to POSIX, using stdout after it has been passed to fclose is >> undefined behavior. > > Yup. We did not detect this bug earlier because on most systems, fflush > returns -1/EBADF in this situation, rather than crashing.
Actually, it returns 0 without setting errno on Linux. And on Solaris, it returns 0 but set errno to EBADF. I think the point that POSIX was trying to make is that _most_ streams are dynamically allocated (via fopen or fdopen), and therefore using them after fclose() is triggering the undefined behavior inherent with using freed memory. But the three std streams are pre-allocated, even though they may start life already mapped to a closed stream. Maybe it's worth asking the Austin group whether the standard streams should be granted exceptional status and given a guarantee to still portably work in other API (well, fail with EBADF)? > >> What's the best way to do that? Have >> close_stdout call freopen("/dev/null","w",stdout) prior to calling error()? > > Yes, this looks like the right fix to me. With "/dev/null" being replaced with > DEV_NULL defined as in lib/pipe.h, for mingw portability. > >> Convince the glibc folks to change error() to not call fflush(stdout) if >> fileno >> (stdout) is closed? > > This would not help: After fclose (stdout), "any use of stdout results in > undefined behavior", says POSIX, hence fileno (stdout) is already undefined > behaviour. Ah, but fileno(stdout) == 1 by definition of STDOUT_FILENO, so you don't have to go via fileno (you can directly use fcntl(1,...) to learn whether the fd has been closed). - -- Don't work too hard, make some time for fun as well! Eric Blake e...@byu.net -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (Cygwin) Comment: Public key at home.comcast.net/~ericblake/eblake.gpg Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iEYEARECAAYFAkphtD4ACgkQ84KuGfSFAYAtlACfab5JvzsM54uZ4nwYU8c4Dz4d MHYAni+kW0ICj/o9Uf/nhAE/1ivMuliT =g/qd -----END PGP SIGNATURE-----