From 1f63e287b62c340deba23a0ec23560db0813242e Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Fri, 6 Sep 2019 22:49:21 +0200 Subject: [PATCH] unix: simplify open(O_CLOEXEC) feature detection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Platforms that support O_CLOEXEC have supported it for a long time and don't need feature detection. Libuv can just assume it works as advertised. The feature detection was broken for old Linux kernels because they don't report EINVAL for unknown open() flags, they simply open the file without setting the FD_CLOEXEC flag. Libuv could fix that by checking afterwards with fcntl() if the flag was actually set but it doesn't support kernels that old in the first place so let's simplify the logic. Fixes: https://github.com/libuv/libuv/issues/2450 PR-URL: https://github.com/libuv/libuv/pull/2454 Reviewed-By: Colin Ihrig Reviewed-By: Santiago Gimeno Reviewed-By: Saúl Ibarra Corretgé --- src/unix/core.c | 32 +++++++++++--------------------- src/unix/fs.c | 17 ++++------------- 2 files changed, 15 insertions(+), 34 deletions(-) diff --git a/src/unix/core.c b/src/unix/core.c index ee52b1f4..366c43c2 100644 --- a/src/unix/core.c +++ b/src/unix/core.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include /* O_CLOEXEC */ #include #include #include @@ -51,9 +51,6 @@ #if defined(__APPLE__) # include -# if defined(O_CLOEXEC) -# define UV__O_CLOEXEC O_CLOEXEC -# endif /* defined(O_CLOEXEC) */ # endif /* defined(__APPLE__) */ @@ -73,7 +70,6 @@ extern char** environ; # include # include # include -# define UV__O_CLOEXEC O_CLOEXEC # if defined(__FreeBSD__) && __FreeBSD__ >= 10 # define uv__accept4 accept4 # endif @@ -1005,24 +1001,17 @@ int uv_getrusage(uv_rusage_t* rusage) { int uv__open_cloexec(const char* path, int flags) { - int err; +#if defined(O_CLOEXEC) int fd; -#if defined(UV__O_CLOEXEC) - static int no_cloexec; + fd = open(path, flags | O_CLOEXEC); + if (fd == -1) + return UV__ERR(errno); - if (!no_cloexec) { - fd = open(path, flags | UV__O_CLOEXEC); - if (fd != -1) - return fd; - - if (errno != EINVAL) - return UV__ERR(errno); - - /* O_CLOEXEC not supported. */ - no_cloexec = 1; - } -#endif + return fd; +#else /* O_CLOEXEC */ + int err; + int fd; fd = open(path, flags); if (fd == -1) @@ -1035,6 +1024,7 @@ int uv__open_cloexec(const char* path, int flags) { } return fd; +#endif /* O_CLOEXEC */ } @@ -1056,7 +1046,7 @@ int uv__dup2_cloexec(int oldfd, int newfd) { static int no_dup3; if (!no_dup3) { do - r = uv__dup3(oldfd, newfd, UV__O_CLOEXEC); + r = uv__dup3(oldfd, newfd, O_CLOEXEC); while (r == -1 && errno == EBUSY); if (r != -1) return r; diff --git a/src/unix/fs.c b/src/unix/fs.c index fc80d00d..fd3dd4c2 100644 --- a/src/unix/fs.c +++ b/src/unix/fs.c @@ -255,20 +255,10 @@ static ssize_t uv__fs_mkdtemp(uv_fs_t* req) { static ssize_t uv__fs_open(uv_fs_t* req) { - static int no_cloexec_support; - int r; - - /* Try O_CLOEXEC before entering locks */ - if (no_cloexec_support == 0) { #ifdef O_CLOEXEC - r = open(req->path, req->flags | O_CLOEXEC, req->mode); - if (r >= 0) - return r; - if (errno != EINVAL) - return r; - no_cloexec_support = 1; -#endif /* O_CLOEXEC */ - } + return open(req->path, req->flags | O_CLOEXEC, req->mode); +#else /* O_CLOEXEC */ + int r; if (req->cb != NULL) uv_rwlock_rdlock(&req->loop->cloexec_lock); @@ -289,6 +279,7 @@ static ssize_t uv__fs_open(uv_fs_t* req) { uv_rwlock_rdunlock(&req->loop->cloexec_lock); return r; +#endif /* O_CLOEXEC */ }