[Top][All Lists]

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

Re: [bug #33134] spurious error when stdout is already closed

From: Philip Guenther
Subject: Re: [bug #33134] spurious error when stdout is already closed
Date: Wed, 20 Apr 2011 22:48:14 -0700

On Wed, Apr 20, 2011 at 9:31 PM, David Boyce <address@hidden> wrote:
> On Thu, Apr 21, 2011 at 12:00 AM, Philip Guenther <address@hidden> wrote:
>> Why is that a mistake?
>> It appears you're saying that make should complain about failures to
>> write to stdout for reasons like EIO, ENOSPC,  and EOVERFLOW, but
>> *not* for EBADF.
> I think you're still not getting my point here. I do not believe this
> has anything to do with *writes* at all, failed or otherwise. Make is
> attempting to close something that's already closed and complaining
> when it doesn't work. POSIX is quite clear that fclose on a closed
> stream results in an error condition.

First, stdout is *NOT* a closed FILE.  It is a FILE that claims to be
attached to an fd that isn't open  There is *NO* provision in the C,
POSIX, or SUS standards for stdout to not be a FILE that can be passed
to the various stdio operations, even if fd 1 is closed and the
underlying operations all result in EBADF.

Next, close_stdout() doesn't just call close(), but rather fclose(),
which is *much* different.  In particular, fclose() flushes stdio
buffers, in which case it will call write().  By failing to call
fclose(), you'll lose any final buffered data.

close_stdout() doesn't just call fclose() but also ferror(), to see if
there was a previous error on the FILE.  It's not uncommon for
programs to leave out some or all error checks for writing to FILEs
and only check at the end, to see whether fclose() failed or similar.
In this case, the difference in error messages (that it didn't include
the "Bad file descriptor") plus the review of the logic shows that
make does *exactly* that.

And yes, write()s *are* failing.

$ cat Makefile
$(info hello)
$ ktrace make  >&-
make: write error: Bad file descriptor
$ kdump | grep write
 31284 gmake    CALL  write(0x1,0x202429000,0x6)
 31284 gmake    RET   write -1 errno 9 Bad file descriptor
 31284 gmake    CALL  write(0x2,0x7f7ffffbf0f0,0x6)
 31284 gmake    RET   write 6
 31284 gmake    CALL  write(0x2,0x7f7ffffbf1d0,0x20)
       "write error: Bad file descriptor"
 31284 gmake    RET   write 32/0x20
 31284 gmake    CALL  write(0x2,0x82b0e7,0x1)
 31284 gmake    RET   write 1

> but I lost the EBADF test when I redid it. That was a mistake, and
> maybe there's a better way of checking for closure than ftell anyway,
> but the basic point of not closing something unless it was open
> remains.

What problem are you trying to solve?  Do you find that fclose(stdout)
is exhibiting some sort of undefined behavior on your systems?

Philip Guenther

reply via email to

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