From 0fde10825e0cc65fa476738a74e631c2aab0752b Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Sun, 24 Jun 2012 06:04:29 +0200 Subject: [PATCH] linux: set close-on-exec flag with ioctl(FIOCLEX) ioctl(FIOCLEX) is 25% faster than fcntl(F_SETFD) on a stock 2.6.32 kernel. --- src/unix/core.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/src/unix/core.c b/src/unix/core.c index b440506a..df5738b0 100644 --- a/src/unix/core.c +++ b/src/unix/core.c @@ -487,17 +487,34 @@ int uv__accept(int sockfd) { } +#if __linux__ + int uv__nonblock(int fd, int set) { int r; -#if FIONBIO do r = ioctl(fd, FIONBIO, &set); while (r == -1 && errno == EINTR); return r; -#else +} + + +int uv__cloexec(int fd, int set) { + int r; + + do + r = ioctl(fd, set ? FIOCLEX : FIONCLEX); + while (r == -1 && errno == EINTR); + + return r; +} + +#else /* !__linux__ */ + +int uv__nonblock(int fd, int set) { int flags; + int r; do r = fcntl(fd, F_GETFL); @@ -516,7 +533,6 @@ int uv__nonblock(int fd, int set) { while (r == -1 && errno == EINTR); return r; -#endif } @@ -524,15 +540,6 @@ 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. - */ - if (set) - flags = FD_CLOEXEC; - else - flags = 0; -#else do r = fcntl(fd, F_GETFD); while (r == -1 && errno == EINTR); @@ -544,7 +551,6 @@ int uv__cloexec(int fd, int set) { flags = r | FD_CLOEXEC; else flags = r & ~FD_CLOEXEC; -#endif do r = fcntl(fd, F_SETFD, flags); @@ -553,6 +559,8 @@ int uv__cloexec(int fd, int set) { return r; } +#endif /* __linux__ */ + /* This function is not execve-safe, there is a race window * between the call to dup() and fcntl(FD_CLOEXEC).