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

unix: don't retry close() on EINTR

Linux 2.6 always closes the file descriptor, even on EINTR. Retrying the close()
call isn't merely useless, it's actively harmful - the file descriptor may have
been acquired by another thread.
  • Loading branch information...
bnoordhuis committed Jan 18, 2012
1 parent 52511b9 commit dee86dd5b06897ae3f5ae0107840f3fd2d3916ed
Showing with 8 additions and 20 deletions.
  1. +0 −17 src/unix/core.c
  2. +8 −3 src/unix/internal.h
@@ -790,23 +790,6 @@ int uv__accept(int sockfd, struct sockaddr* saddr, socklen_t slen) {
}


int uv__close(int fd) {
int status;

/*
* Retry on EINTR. You may think this is academic but on linux
* and probably other Unices too, close(2) is interruptible.
* Failing to handle EINTR is a common source of fd leaks.
*/
do {
status = close(fd);
}
while (status == -1 && errno == EINTR);

return status;
}


int uv__nonblock(int fd, int set) {
#if FIONBIO
return ioctl(fd, FIONBIO, &set);
@@ -154,14 +154,19 @@ enum {
UV_TCP_KEEPALIVE = 0x100 /* Turn on keep-alive. */
};

int uv__close(int fd);
/* core */
void uv__handle_init(uv_loop_t* loop, uv_handle_t* handle, uv_handle_type type);


int uv__nonblock(int fd, int set) __attribute__((unused));
int uv__cloexec(int fd, int set) __attribute__((unused));
int uv__socket(int domain, int type, int protocol);

/* We used to handle EINTR in uv__close() but linux 2.6 will have closed the
* file descriptor anyway, even on EINTR. Retrying in that case isn't merely
* useless, it's actively harmful - the file descriptor may have been acquired
* by another thread.
*/
#define uv__close(fd) close(fd)

/* error */
uv_err_code uv_translate_sys_error(int sys_errno);
void uv_fatal_error(const int errorno, const char* syscall);

0 comments on commit dee86dd

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