unix: clean up uv_fs_open() O_CLOEXEC logic
Move the logic out of uv__fs_work() and into a function of its own. PR-URL: https://github.com/libuv/libuv/pull/326 Reviewed-By: Saúl Ibarra Corretgé <saghul@gmail.com>
This commit is contained in:
parent
1f711e4d6d
commit
202195c2f4
@ -202,6 +202,44 @@ 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 */
|
||||
}
|
||||
|
||||
if (req->cb != NULL)
|
||||
uv_rwlock_rdlock(&req->loop->cloexec_lock);
|
||||
|
||||
r = open(req->path, req->flags, req->mode);
|
||||
|
||||
/* In case of failure `uv__cloexec` will leave error in `errno`,
|
||||
* so it is enough to just set `r` to `-1`.
|
||||
*/
|
||||
if (r >= 0 && uv__cloexec(r, 1) != 0) {
|
||||
r = uv__close(r);
|
||||
if (r != 0 && r != -EINPROGRESS)
|
||||
abort();
|
||||
r = -1;
|
||||
}
|
||||
|
||||
if (req->cb != NULL)
|
||||
uv_rwlock_rdunlock(&req->loop->cloexec_lock);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
static ssize_t uv__fs_read(uv_fs_t* req) {
|
||||
#if defined(__linux__)
|
||||
static int no_preadv;
|
||||
@ -743,9 +781,6 @@ static void uv__fs_work(struct uv__work* w) {
|
||||
int retry_on_eintr;
|
||||
uv_fs_t* req;
|
||||
ssize_t r;
|
||||
#ifdef O_CLOEXEC
|
||||
static int no_cloexec_support;
|
||||
#endif /* O_CLOEXEC */
|
||||
|
||||
req = container_of(w, uv_fs_t, work_req);
|
||||
retry_on_eintr = !(req->fs_type == UV_FS_CLOSE);
|
||||
@ -774,6 +809,7 @@ static void uv__fs_work(struct uv__work* w) {
|
||||
X(LINK, link(req->path, req->new_path));
|
||||
X(MKDIR, mkdir(req->path, req->mode));
|
||||
X(MKDTEMP, uv__fs_mkdtemp(req));
|
||||
X(OPEN, uv__fs_open(req));
|
||||
X(READ, uv__fs_read(req));
|
||||
X(SCANDIR, uv__fs_scandir(req));
|
||||
X(READLINK, uv__fs_readlink(req));
|
||||
@ -785,41 +821,10 @@ static void uv__fs_work(struct uv__work* w) {
|
||||
X(UNLINK, unlink(req->path));
|
||||
X(UTIME, uv__fs_utime(req));
|
||||
X(WRITE, uv__fs_write(req));
|
||||
case UV_FS_OPEN:
|
||||
#ifdef O_CLOEXEC
|
||||
/* Try O_CLOEXEC before entering locks */
|
||||
if (!no_cloexec_support) {
|
||||
r = open(req->path, req->flags | O_CLOEXEC, req->mode);
|
||||
if (r >= 0)
|
||||
break;
|
||||
if (errno != EINVAL)
|
||||
break;
|
||||
no_cloexec_support = 1;
|
||||
}
|
||||
#endif /* O_CLOEXEC */
|
||||
if (req->cb != NULL)
|
||||
uv_rwlock_rdlock(&req->loop->cloexec_lock);
|
||||
r = open(req->path, req->flags, req->mode);
|
||||
|
||||
/*
|
||||
* In case of failure `uv__cloexec` will leave error in `errno`,
|
||||
* so it is enough to just set `r` to `-1`.
|
||||
*/
|
||||
if (r >= 0 && uv__cloexec(r, 1) != 0) {
|
||||
r = uv__close(r);
|
||||
if (r != 0 && r != -EINPROGRESS)
|
||||
abort();
|
||||
r = -1;
|
||||
}
|
||||
if (req->cb != NULL)
|
||||
uv_rwlock_rdunlock(&req->loop->cloexec_lock);
|
||||
break;
|
||||
default: abort();
|
||||
}
|
||||
|
||||
#undef X
|
||||
}
|
||||
while (r == -1 && errno == EINTR && retry_on_eintr);
|
||||
} while (r == -1 && errno == EINTR && retry_on_eintr);
|
||||
|
||||
if (r == -1)
|
||||
req->result = -errno;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user