Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files

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.
  • Loading branch information...
bnoordhuis committed Jun 24, 2012
1 parent e21cdf1 commit 0fde10825e0cc65fa476738a74e631c2aab0752b
Showing with 21 additions and 13 deletions.
  1. +21 −13 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,23 +533,13 @@ int uv__nonblock(int fd, int set) {
while (r == -1 && errno == EINTR);

return r;
#endif
}


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).

0 comments on commit 0fde108

Please sign in to comment.
You can’t perform that action at this time.