Write to a closed stream bug.

Richard B. Johnson (root@chaos.analogic.com)
Wed, 17 Dec 1997 14:51:37 -0500 (EST)

I discovered a bug in the new glibc 'C' runtime library that has
far-reaching consequences if one were to recompile existing Linux
support software.

I have been communicating privately with GNU. Unfortunately, the
response has been that I don't know what I'm talking about and
that the bug isn't a bug at all.

It is now time for the Linux group to review the consequences of
having such a bug in the C runtime library. Hopefully, more
persons than myself will declare that the current behavior is
unacceptable and force it to be fixed.

The glibc bug is that a write to a closed file descriptor does not
return an error.

This is definitely a bug. If the standards, proposed or existing,
allow this behavior, the standards are wrong. No 'C' runtime library
that I have checked during the past two weeks has allowed this behavior.

A library function must perform its intended function or return
information in some manner that shows why the function could not
be performed. It is entirely unacceptable for any function, whether
it is in a runtime-library, or is coded by an application, to
pretend that it performed some function that, in fact, it did not.

There is a name for such behavior and it isn't something professionals
have to use very often.

The current implementation, as demonstrated, pretends that it does
something that it did not do.

#include <stdio.h>
#include <errno.h>

int main()
int i;
FILE *file;
file = fopen("/tmp/foo", "w");
i = fprintf(file, "12345678");
printf("Returned %d %s\n", i, strerror(errno));

The proposed standard you cited:

> The current ISO C9X draft says in 7.13.3:
> [#4] A file may be disassociated from a controlling stream
> by closing the file. Output streams are flushed (any
> unwritten buffer contents are transmitted to the host
> environment) before the stream is disassociated from the
> file. The value of a pointer to a FILE object is
> indeterminate after the associated file is closed (including
> the standard text streams). Whether a file of zero length
> (on which no characters have been written by an output
> stream) actually exists is implementation-defined.

file. The value of a pointer to a FILE object is
indeterminate after the associated file is closed (including

This does not relate to the observed bug at all.

This says that you can make the VALUE of the pointer anything you
wish after the file was closed. Therefore you can leave its VALUE
alone or you can change it to NULL (as some do), or you can do anything
else to its VALUE. This allows your library to release any storage
associated with the FILE object, or trap subsequent attempts to
use that pointer after the file was closed, etc.

It says nothing about attempting to write data to a closed file. Some
implementations change the value of the pointer to NULL when the file
is closed, this allows one to detect user program bugs by seg-faulting
if an attempt is made to use that pointer again.

This does not fix the observed behavior unless a close(fd) results in
any associated FILE object being set to NULL as well.

The current 'C' standard (ANSI C3.159-1989, called POSIX) also provides:

printf(3S) Standard I/O Functions printf(3S)

printf, fprintf, sprintf - print formatted output

#include <stdio.h>


printf(), fprintf(), and sprintf() return the number of
characters transmitted, or return a negative value if an
error was encountered.

Richard B. Johnson
Project Engineer
Analogic Corporation
Penguin : Linux version 2.1.70 on an i586 machine (66.15 BogoMips).
Warning : It's hard to remain at the trailing edge of technology.