Sources Bugzilla – Bug 14627
close() should set errno to EINPROGRESS when interrupted by a signal
Last modified: 2012-09-26 04:32:59 UTC
Background: Historically, there has been a disagreement over the behavior of
close() when interrupted by a signal. Some implementations (e.g. HPUX) had it
leave the file descriptor open when returning with EINTR; others (Linux, AIX)
closed it unconditionally, but returned with EINTR if a signal arrived while
close() was interrupted before returning. This ambiguity was acceptable for
single-threaded applications, which could just unconditionally call close()
again on EINTR, possibly getting EBADF if the file descriptor no longer existed
due to the Linux/AIX behavior. It's not acceptable for multi-threaded
applications, where calling close again could close a file descriptor just
obtained by another thread - which can have far-reaching and extremely
The issue was referred to the Austin Group for interpretation (as defect #529,
http://austingroupbugs.net/view.php?id=529), and was resolved by:
1) Requiring the HPUX behavior, leaving the file descriptor open, if close()
returns with EINTR.
2) Allowing implementations that do not want to offer this behavior to return
with EINPROGRESS instead of EINTR to indicate that close() did not finish
waiting for the file/device to finish closing, but that the file descriptor has
3) Defining a new posix_close() function with a flag to control the behavior.
Reportedly, the Linux kernel developers are vehemently opposed to changing the
behavior of close/EINTR to match HPUX, so I think it's safe to say the behavior
of the kernel will not change. Some links to discussions and information on
their opinions can be found here:
For what it's worth, I agree with them that having close() return without
having deallocated the file descriptor is a highly undesirable behavior.
However, it's also wrong (and now non-conformant, with the final accepted text
from Austin Group defect #529 applied to POSIX) to return with EINTR, an error
code which means the side effects of the function did not take place, when the
side effects did in fact take place.
Fortunately, the revised text in POSIX gives an easy-out that should make
everybody happy: the option to return with EINPROGRESS.
Since the kernel developers seem to be uninterested in changing the kernel to
return EINPROGRESS (and even if they did, it would not fix the issue on older
kernels), I propose that glibc catch the EINTR error from close() on Linux and
remap it to EINPROGRESS. If Linux ever catches up and starts returning
EINPROGRESS directly, nothing will break. The only possible breakage would be
if, at some point in the future, Linux starts returning EINTR with the real
EINTR semantics (HPUX semantics), but I'm pretty sure this is not going to
happen given the developers' attitudes on the matter.