Date: Wed, 22 Nov 2000 09:36:11 -0800 (PST) From: Matt Dillon <dillon@earth.backplane.com> To: Robert Nordier <rnordier@nordier.com> Cc: dcs@newsguy.com (Daniel C. Sobral), drosih@rpi.edu (Garance A Drosihn), hackers@FreeBSD.ORG Subject: Re: fclose vs ferror (from libc/getcap) Message-ID: <200011221736.eAMHaBK13156@earth.backplane.com> References: <200011221225.OAA04292@siri.nordier.com>
next in thread | previous in thread | raw e-mail | index | archive | help
When you look at the fclose()/ferror() problem you have to look at it in its historical context. Historically some versions of UNIX had very odd semantics. For example, many programmers depended on free()'d data being left intact at least until the next free(). It was even documented to have that behavior at one time (though I forget where, this was a long time ago). Similarly, close() didn't always return an integer... it used to be a void function on many systems, or return garbage (i.e. be mis-implemented) and thus undependable. And fclose() also used to be a void function on many systems or have an undependable return value. Enough confusion occured from these differences that some programmers often took liberties way back then that are obivously illegal today.. for example, calling ferror() after fclose() (because fclose() didn't used to return the final flush status), rather then using the more portable fflush/ferror/fclose combination. Another example is freopen()ing an fclose()'d file, especially in regards to stdin, stdout, and stderr. This confusion is further exasperated by shortcuts taken inside libc itself... for example, libc declares stdin, stdout and stderr as static structures and the exit code just assumes those pointers point to good memory, even if the streams have been closed. Many programmers use library code as a basis for learning the APIs and mistakenly come to believe that they can make similar assumptions externally that the library makes internally. In today's world the standard is: When you free() something, that's it.. it's gone. When you fclose() something or otherwise terminate a structure, it's gone. Anything else is illegal. *internally* our libc assumes that ferror() is legal after an fclose() because, well, it's true... but only for internal library functions. Nobody outside the library can legally make that assumption and it could also be argued that even within the library those types of assumptions should not be made unless absolutely necessary. There isn't much we can do about the issue except fix the instances of mis-programming as they show up. -Matt To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200011221736.eAMHaBK13156>