Skip to content
This repository has been archived by the owner on May 4, 2018. It is now read-only.

Commit

Permalink
linux: set close-on-exec flag with ioctl(FIOCLEX)
Browse files Browse the repository at this point in the history
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 0fde108
Showing 1 changed file with 21 additions and 13 deletions.
34 changes: 21 additions & 13 deletions src/unix/core.c
Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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).
Expand Down

0 comments on commit 0fde108

Please sign in to comment.