close should not be cancellable after "failing" with EINTR
authorRich Felker <dalias@aerifal.cx>
Sun, 7 Aug 2011 04:05:01 +0000 (00:05 -0400)
committerRich Felker <dalias@aerifal.cx>
Sun, 7 Aug 2011 04:05:01 +0000 (00:05 -0400)
normally we allow cancellation to be acted upon when a syscall fails
with EINTR, since there is no useful status to report to the caller in
this case, and the signal that caused the interruption was almost
surely the cancellation request, anyway.

however, unlike all other syscalls, close has actually performed its
resource-deallocation function whenever it returns, even when it
returned an error. if we allow cancellation at this point, the caller
has no way of informing the program that the file descriptor was
closed, and the program may later try to close the file descriptor
again, possibly closing a different, newly-opened file.

the workaround looks ugly (special-casing one syscall), but it's
actually the case that close is the one and only syscall (at least
among cancellation points) with this ugly property.

src/thread/cancel_impl.c

index 4f78a63a84ccc87c6736abb8b5c2589a14755f34..01f52b82c7a20575e6162cedd958e071059f4b51 100644 (file)
@@ -27,7 +27,8 @@ long (__syscall_cp)(long nr, long u, long v, long w, long x, long y, long z)
        r = __syscall_cp_asm(&self->cp_sp, nr, u, v, w, x, y, z);
        self->cp_ip = old_ip;
        self->cp_sp = old_sp;
-       if (r == -EINTR && self->cancel && !self->canceldisable) __cancel();
+       if (r==-EINTR && nr!=SYS_close && self->cancel && !self->canceldisable)
+               __cancel();
        return r;
 }