Hello all, Following a discussion [4][5] (and a bit of education for me, thanks to Rich Felker) on the GNU C Library (libc-alpha) mailing list, I have some questions about bug 529 [0].
1. If I understand correctly, the proposed changes for Issue 8 will in effect declare to be broken those existing applications that treat EINTR from close() as "the file is closed". (I.e., per the proposed changes [7], implementations will not be allowed to have close() fail with EINTR while also closing the file.) However, those existing applications are behaving correctly in terms of what the implementations do. Is my understanding of the intentions of the Issue 8 changes correct? If yes, I presume the path is that such applications would be conformant to older POSIX, but won't be conformant to Issue 8. (Right?) 2. From the bug thread, I've missed something. I understand the argument that EINTR was being treated inconsistently for close() on Linux and other systems, but the thing is that implementations with the close() "EINTR means the file descriptor is closed" behavior exist, and seem even to be common. Why (given the variation in existing implementations) was the decision taken to change the specification for close() , instead of just adding a new posix_close() that addresses the problem? 3. [An observation, not a question] As far as I can tell, the Linux behavior for close() EINTR semantics is not an isolated case. One can see this in the FreeBSD close(2) manual page [1] and in the AIX [2] manual page. It seems also to be the norm for other implementations (see my next point). HP-UX claims [6] in the documentation to leave the file open on EINTR, but unfortunately, the source code isn't publicly available to verify this 4. The interpretation for bug 529 doesn't address a wider issue. On several implementations, the FD is always closed *for any error* that close() may return. That is what Linux does (the FD is released very early in the "close" processing, and errors may be reported afterward). It's also what FreeBSD does, as documented in its close(2) man page: In case of any error except EBADF, the supplied file descriptor is deallocated and therefore is no longer valid. (By the way, that text seems to have been added in FreeBSD 9.1, in early 2012, I presume to document existing behavior after someone read this Austin bug report.) For info, FreeBSD documents the following errors for close(): EBADF, EINTR, ENOSPC, and ECONNRESET. Looking at some historical source code (mostly from [3]) 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 [3]), 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. So, my summary here is that many (perhaps most?) implementations are similar to Linux and FreeBSD, but this isn't currently addressed in POSIX, so far as I can tell. Should it be? Cheers, Michael [0] http://austingroupbugs.net/view.php?id=529 [1] https://www.freebsd.org/cgi/man.cgi?query=close&apropos=0&sektion=0&manpath=FreeBSD+10.3-RELEASE+and+Ports&arch=default&format=html#ERRORS [2] http://publib16.boulder.ibm.com/doc_link/en_US/a_doc_lib/libs/basetrf1/close.htm [3] https://archive.org/download/various_operating_system_source_code [4] https://sourceware.org/ml/libc-alpha/2016-12/msg00110.html [5] https://sourceware.org/ml/libc-alpha/2016-12/msg00136.html [6] http://www.unix.com/man-page/hpux/2/close/ [7] http://austingroupbugs.net/view.php?id=529#c1200