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) {
|
static ssize_t uv__fs_read(uv_fs_t* req) {
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
static int no_preadv;
|
static int no_preadv;
|
||||||
@ -743,9 +781,6 @@ static void uv__fs_work(struct uv__work* w) {
|
|||||||
int retry_on_eintr;
|
int retry_on_eintr;
|
||||||
uv_fs_t* req;
|
uv_fs_t* req;
|
||||||
ssize_t r;
|
ssize_t r;
|
||||||
#ifdef O_CLOEXEC
|
|
||||||
static int no_cloexec_support;
|
|
||||||
#endif /* O_CLOEXEC */
|
|
||||||
|
|
||||||
req = container_of(w, uv_fs_t, work_req);
|
req = container_of(w, uv_fs_t, work_req);
|
||||||
retry_on_eintr = !(req->fs_type == UV_FS_CLOSE);
|
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(LINK, link(req->path, req->new_path));
|
||||||
X(MKDIR, mkdir(req->path, req->mode));
|
X(MKDIR, mkdir(req->path, req->mode));
|
||||||
X(MKDTEMP, uv__fs_mkdtemp(req));
|
X(MKDTEMP, uv__fs_mkdtemp(req));
|
||||||
|
X(OPEN, uv__fs_open(req));
|
||||||
X(READ, uv__fs_read(req));
|
X(READ, uv__fs_read(req));
|
||||||
X(SCANDIR, uv__fs_scandir(req));
|
X(SCANDIR, uv__fs_scandir(req));
|
||||||
X(READLINK, uv__fs_readlink(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(UNLINK, unlink(req->path));
|
||||||
X(UTIME, uv__fs_utime(req));
|
X(UTIME, uv__fs_utime(req));
|
||||||
X(WRITE, uv__fs_write(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();
|
default: abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef X
|
#undef X
|
||||||
}
|
} while (r == -1 && errno == EINTR && retry_on_eintr);
|
||||||
while (r == -1 && errno == EINTR && retry_on_eintr);
|
|
||||||
|
|
||||||
if (r == -1)
|
if (r == -1)
|
||||||
req->result = -errno;
|
req->result = -errno;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user