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.
This commit is contained in:
Ben Noordhuis 2012-06-24 06:04:29 +02:00
parent e21cdf1e0d
commit 0fde10825e

View File

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