From b3a97f89812b19b67a35906ad4ca7eb850be28f0 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Thu, 14 Jun 2012 00:44:58 +0200 Subject: [PATCH] unix: make uv__cloexec() EINTR resilient It's somewhat underspecified if and when fcntl() can return EINTR. It never does on Linux for F_GETFD or F_SETFD but let's not make any assumptions. --- src/unix/core.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/src/unix/core.c b/src/unix/core.c index 1296aae1..a9c49f08 100644 --- a/src/unix/core.c +++ b/src/unix/core.c @@ -487,30 +487,36 @@ int uv__nonblock(int fd, int set) { int uv__cloexec(int fd, int set) { + int flags; + int r; + #if __linux__ /* Linux knows only FD_CLOEXEC so we can safely omit the fcntl(F_GETFD) * syscall. CHECKME: That's probably true for other Unices as well. */ - return fcntl(fd, F_SETFD, set ? FD_CLOEXEC : 0); + if (set) + flags = FD_CLOEXEC; + else + flags = 0; #else - int flags; + do + r = fcntl(fd, F_GETFD); + while (r == -1 && errno == EINTR); - if ((flags = fcntl(fd, F_GETFD)) == -1) { + if (r == -1) return -1; - } - if (set) { - flags |= FD_CLOEXEC; - } else { - flags &= ~FD_CLOEXEC; - } - - if (fcntl(fd, F_SETFD, flags) == -1) { - return -1; - } - - return 0; + if (set) + flags = r | FD_CLOEXEC; + else + flags = r & ~FD_CLOEXEC; #endif + + do + r = fcntl(fd, F_SETFD, flags); + while (r == -1 && errno == EINTR); + + return r; }