Looking at some historical source code (mostly from [1]) suggests
that the "close() always closes regardless of error return"
behavior has a long history, predating even POSIX.1-1990.
For example, in SVR4 for x86 (from the file sysvr4.tar.bz2 at
[1]), we see the following:
int
close(uap, rvp)
register struct closea *uap;
rval_t *rvp;
{
file_t *fp;
register int error;
if (error = getf(uap->fdes, &fp))
return error;
error = closef(fp);
setf(uap->fdes, NULLFP);
return error;
}
In the above, getf() can return EBADF. The other errors are
returned by closef(), but the file descriptor is deallocated
regardless of errors by setf().
A similar pattern seems to have been preserved into at least late
OpenSolaris days (verified from looking at the initial commit of
the illumos source code). There we find the following in
closeandsetf() (called by close()):
error = closef(fp);
setf(fd, newfp);
return (error);
Looking at the code of closef() in AIX 4.1.3 suggests that, as on
on Linux and FreeBSD, the open file is always released, regardless
of errors.
For Irix, 6.5.5, I'm not sure (the code is not so easy to quickly
read); it may be that it does return errors while leaving the FD
open.
[1] https://archive.org/download/various_operating_system_source_code
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
.\" filp_close()
such as flushing data to the filesystem or device,
occur only later in the close operation.
+(Several other implementations similarly always close the file descriptor,
+.\" FreeBSD documents this explitly. From the look of the source code
+.\" SVR4, ancient SunOS, later Solaris, and AIX all do this.
+even if they subsequently report an error on return from
+.BR close ().)
A careful programmer who wants to know about I/O errors may precede
.BR close ()