POSIX close(2) is broken
Link to the standard:<p><a href="http://pubs.opengroup.org/onlinepubs/000095399/functions/close.html" rel="nofollow">http://pubs.opengroup.org/onlinepubs/000095399/functions/clo...</a><p>Some discussion that is related to this:<p><a href="http://lwn.net/Articles/365294/" rel="nofollow">http://lwn.net/Articles/365294/</a><p><a href="http://stackoverflow.com/questions/7297001/if-close2-fails-with-eio-will-the-file-descriptor-still-be-deleted" rel="nofollow">http://stackoverflow.com/questions/7297001/if-close2-fails-w...</a><p>Something which I would consider to be "the answer" from Linus for Linux:<p><a href="http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html" rel="nofollow">http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000...</a><p><a href="http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3171.html" rel="nofollow">http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3171...</a><p><a href="http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3202.html" rel="nofollow">http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3202...</a><p>(Apparently, the first thing Linux does is deallocate the file descriptor; /then/ it starts flushing pending written data. If this process is interrupted, it will return EINTR, but the file descriptor itself is already deallocated, and may have been reused long before close() returned.)<p>Honestly, after reviewing all of this material, I think the author of this post might simply not know what "unspecified" means (or, alternatively, is making an abstract problem sound overly concrete and blown somewhat out of proportion).<p>When a specification says "unspecified", it doesn't mean "unknown at runtime, could be anything nondeterministically". It only means that the standard did not specify the result.<p>Often, this is because there is either a historical artifact or reasonable practical constraint that was posed by one or more vendors that were implementing the standard that meant different implementations simply /weren't/ going to agree on any one value.<p>However, for any given implementation, there very likely might be a correct answer. In the case of Linux, you should not retry calls to close(): the primary maintainer has told us that it deterministically guarantees the file descriptor is closed even if the function returns EINTR (critical edit: the wording of this sentence was incorrect in original draft).<p>That said, there may be another implementation out there, possibly one we may use (but with a standard like this, could easily be one that we have never heard of and that already died a death of obscurity years ago) that has the opposite behavior: where EINTR interrupts something (such as pending writes) before the file descriptor is closed, requiring developers to retry.<p>It is, however, unfortunate that this happened, and the author is right about issues for developers who attempt to use this API "without assuming more than the standard specified".<p>That said, there may be other options, such as using SA_RESTART, as argued in this discussion I just found (which also happens to talk about the meaning of "unspecified" ;P):<p><a href="http://permalink.gmane.org/gmane.os.hurd.devel.readers/265" rel="nofollow">http://permalink.gmane.org/gmane.os.hurd.devel.readers/265</a><p>(edit:) Oh, and people may find it interesting that standards like this are often modified over time, with "interpretations" and outright edits. As an example, here is some vaguely related discussion regarding closing file descriptors during process termination:<p><a href="http://austingroupbugs.net/view.php?id=498" rel="nofollow">http://austingroupbugs.net/view.php?id=498</a><p>(edit:) Some more existing discussion:<p><a href="https://sites.google.com/site/michaelsafyan/software-engineering/checkforeintrwheninvokingclosethinkagain" rel="nofollow">https://sites.google.com/site/michaelsafyan/software-enginee...</a><p><a href="http://lists.freebsd.org/pipermail/freebsd-threads/2010-August/004866.html" rel="nofollow">http://lists.freebsd.org/pipermail/freebsd-threads/2010-Augu...</a><p><a href="http://unix.derkeiler.com/Newsgroups/comp.unix.programmer/2009-01/msg00155.html" rel="nofollow">http://unix.derkeiler.com/Newsgroups/comp.unix.programmer/20...</a><p><a href="http://www.cpptalk.net/image-vp121851.html" rel="nofollow">http://www.cpptalk.net/image-vp121851.html</a><p><a href="http://programming.itags.org/unix-linux-programming/79468/" rel="nofollow">http://programming.itags.org/unix-linux-programming/79468/</a><p>Another (very long) Linux-specific thread involving some more responses from Linus:<p><a href="http://lkml.indiana.edu/hypermail/linux/kernel/0207.2/0391.html" rel="nofollow">http://lkml.indiana.edu/hypermail/linux/kernel/0207.2/0391.h...</a><p><a href="http://lkml.indiana.edu/hypermail/linux/kernel/0207.2/0409.html" rel="nofollow">http://lkml.indiana.edu/hypermail/linux/kernel/0207.2/0409.h...</a><p><a href="http://lkml.indiana.edu/hypermail/linux/kernel/0207.2/1173.html" rel="nofollow">http://lkml.indiana.edu/hypermail/linux/kernel/0207.2/1173.h...</a><p>In this thread we also find someone else claiming the standard is "broken":<p><a href="http://lkml.indiana.edu/hypermail/linux/kernel/0207.2/0413.html" rel="nofollow">http://lkml.indiana.edu/hypermail/linux/kernel/0207.2/0413.h...</a><p>With a possibly not useful response, that at least demonstrates that the examples from the specification did not retry:<p><a href="http://lkml.indiana.edu/hypermail/linux/kernel/0207.2/0395.html" rel="nofollow">http://lkml.indiana.edu/hypermail/linux/kernel/0207.2/0395.h...</a>