mailing list of musl libc
 help / color / mirror / code / Atom feed
* close() failure, EINTR, cancellation
@ 2011-08-07  4:02 Rich Felker
  0 siblings, 0 replies; only message in thread
From: Rich Felker @ 2011-08-07  4:02 UTC (permalink / raw)
  To: musl

I've been following up on the previous thread where Vasiliy Kulikov
and I discussed dangers of close failure, and this is what I've found.
On Linux,

1. The close syscall always deallocates the file descriptor, even if
it "fails". There's never any danger of "leaking" file descriptors
from close failure.

2. As such, the close syscall is not restartable if interrupted by a
signal, because the resource it's operating on was already
deallocated. The kernel takes care to replace ERESTARTSYS etc. with
EINTR before returning to userspace.

3. This means close can fail with EINTR even when signal handlers were
all installed with SA_RESTART.

Hopefully the previously discussed security issue has been laid to
rest by this, but a new issue has been raised: what should pthread
cancellation do to close?

There are two considerations: what does POSIX require, and what's
necessary to write robust applications?

For POSIX conformance, close must check for cancellation at least once
somewhere during the operation, and it must not remain
blocked/sleeping while a cancellation request is pending.

For the latter consideration, an application must always be able to
detect whether the file descriptor was deallocated or not. Otherwise
it will leak a file descriptor (if the application thinks it was
deallocated but it wasn't) or it will wrongly retry closing a file
descriptor that was already closed, possibly closing the wrong file.

The possible behaviors compatible with both requirements are:
1. close always closes the fd, but may never return if cancelled.
2. close is only cancellable before closing the fd, and always returns
if it successfully deallocated the fd.

I don't like option 1 because it's very counter-intuitive (differs
from the usual expectation that cancellation indicates the operation
did not successfully complete) and hard to implement without race
conditions that could lead to uncancellable blocking.

For now I'm going with option 2. It seems like the natural behavior
and it requires only minimal changes (special-casing of SYS_close, the
only syscall that fails with EINTR after succeeding) to musl.

If anyone thinks this sounds wrong, please jump in with ideas.

Rich



^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2011-08-07  4:02 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-07  4:02 close() failure, EINTR, cancellation Rich Felker

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).