dbuenzli / bos

Basic OS interaction for OCaml
http://erratique.ch/software/bos
ISC License
64 stars 16 forks source link

Linux close fd, EINTR, no need to retry #72

Open tomjridge opened 7 years ago

tomjridge commented 7 years ago

Under Linux, it is probably the case that the close call is guaranteed to close a valid fd, even if it subsequently reports an error such as EINTR.

So we should not try to close the fd again.

The current code is fine (for the non-concurrent use case), but perhaps a bit misleading:

let rec close fd = try Unix.close fd with
| Unix.Unix_error (Unix.EINTR, _, _) -> close fd

Linux man page for close has:

This permits the behavior that occurs on Linux and many other implementations, where, as with other errors that may be reported by close(), the file descriptor is guaranteed to be closed. However, it also permits another possibility: that the implementation returns an EINTR error and keeps the file descriptor open. (According to its documentation, HP-UX's close() does this.) The caller must then once more use close() to close the file descriptor, to avoid file descriptor leaks. This divergence in implementation behaviors provides a difficult hurdle for portable applications, since on many implementations, close() must not be called again after an EINTR error, and on at least one, close() must be called again. There are plans to address this conundrum for the next major release of the POSIX.1 standard.

Which seems to imply that close must be special-cased to the architecture (but why isn't this handled by libc?)