unix,win: add uv_fs_lchown()

Fixes: https://github.com/libuv/libuv/issues/1790
PR-URL: https://github.com/libuv/libuv/pull/1826
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
This commit is contained in:
Paolo Greppi 2018-04-27 21:58:57 +02:00 committed by cjihrig
parent f8abdf67f8
commit 33b6db3909
No known key found for this signature in database
GPG Key ID: 7434390BDBE9B9C5
5 changed files with 73 additions and 1 deletions

View File

@ -92,6 +92,7 @@ Data types
UV_FS_READLINK,
UV_FS_CHOWN,
UV_FS_FCHOWN,
UV_FS_LCHOWN,
UV_FS_REALPATH,
UV_FS_COPYFILE
} uv_fs_type;
@ -358,14 +359,17 @@ API
.. c:function:: int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb)
.. c:function:: int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_os_fd_t file, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb)
.. c:function:: int uv_fs_lchown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid, uv_gid_t gid, uv_fs_cb cb)
Equivalent to :man:`chown(2)` and :man:`fchown(2)` respectively.
Equivalent to :man:`chown(2)`, :man:`fchown(2)` and :man:`lchown(2)` respectively.
.. note::
These functions are not implemented on Windows.
.. versionchanged:: 2.0.0 replace uv_file with uv_os_fd_t
.. versionchanged:: 2.0.0 implemented uv_fs_lchown
.. c:function:: uv_fs_type uv_fs_get_type(const uv_fs_t* req)
Returns `req->fs_type`.

View File

@ -1200,6 +1200,7 @@ typedef enum {
UV_FS_READLINK,
UV_FS_CHOWN,
UV_FS_FCHOWN,
UV_FS_LCHOWN,
UV_FS_REALPATH,
UV_FS_COPYFILE
} uv_fs_type;
@ -1406,6 +1407,12 @@ UV_EXTERN int uv_fs_fchown(uv_loop_t* loop,
uv_uid_t uid,
uv_gid_t gid,
uv_fs_cb cb);
UV_EXTERN int uv_fs_lchown(uv_loop_t* loop,
uv_fs_t* req,
const char* path,
uv_uid_t uid,
uv_gid_t gid,
uv_fs_cb cb);
enum uv_fs_event {

View File

@ -1146,6 +1146,7 @@ static void uv__fs_work(struct uv__work* w) {
X(COPYFILE, uv__fs_copyfile(req));
X(FCHMOD, fchmod(req->file, req->mode));
X(FCHOWN, fchown(req->file, req->uid, req->gid));
X(LCHOWN, lchown(req->path, req->uid, req->gid));
X(FDATASYNC, uv__fs_fdatasync(req));
X(FSTAT, uv__fs_fstat(req->file, &req->statbuf));
X(FSYNC, uv__fs_fsync(req));
@ -1272,6 +1273,20 @@ int uv_fs_fchown(uv_loop_t* loop,
}
int uv_fs_lchown(uv_loop_t* loop,
uv_fs_t* req,
const char* path,
uv_uid_t uid,
uv_gid_t gid,
uv_fs_cb cb) {
INIT(LCHOWN);
PATH;
req->uid = uid;
req->gid = gid;
POST;
}
int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_os_fd_t file, uv_fs_cb cb) {
INIT(FDATASYNC);
req->file = file;

View File

@ -1913,6 +1913,10 @@ static void fs__fchown(uv_fs_t* req) {
}
static void fs__lchown(uv_fs_t* req) {
req->result = 0;
}
static void uv__fs_work(struct uv__work* w) {
uv_fs_t* req;
@ -1950,6 +1954,7 @@ static void uv__fs_work(struct uv__work* w) {
XX(REALPATH, realpath)
XX(CHOWN, chown)
XX(FCHOWN, fchown);
XX(LCHOWN, lchown);
default:
assert(!"bad uv_fs_type");
}
@ -2236,6 +2241,19 @@ int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_os_fd_t hFile, uv_uid_t uid,
}
int uv_fs_lchown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid,
uv_gid_t gid, uv_fs_cb cb) {
int err;
INIT(UV_FS_LCHOWN);
err = fs__capture_path(req, path, NULL, cb != NULL);
if (err) {
return uv_translate_sys_error(err);
}
POST;
}
int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) {
int err;

View File

@ -86,6 +86,7 @@ static int chmod_cb_count;
static int fchmod_cb_count;
static int chown_cb_count;
static int fchown_cb_count;
static int lchown_cb_count;
static int link_cb_count;
static int symlink_cb_count;
static int readlink_cb_count;
@ -245,6 +246,13 @@ static void chown_cb(uv_fs_t* req) {
uv_fs_req_cleanup(req);
}
static void lchown_cb(uv_fs_t* req) {
ASSERT(req->fs_type == UV_FS_LCHOWN);
ASSERT(req->result == 0);
lchown_cb_count++;
uv_fs_req_cleanup(req);
}
static void chown_root_cb(uv_fs_t* req) {
ASSERT(req->fs_type == UV_FS_CHOWN);
#if defined(_WIN32) || defined(__MSYS__)
@ -1524,6 +1532,7 @@ TEST_IMPL(fs_chown) {
/* Setup. */
unlink("test_file");
unlink("test_file_link");
loop = uv_default_loop();
@ -1567,6 +1576,24 @@ TEST_IMPL(fs_chown) {
uv_run(loop, UV_RUN_DEFAULT);
ASSERT(fchown_cb_count == 1);
/* sync link */
r = uv_fs_link(NULL, &req, "test_file", "test_file_link", NULL);
ASSERT(r == 0);
ASSERT(req.result == 0);
uv_fs_req_cleanup(&req);
/* sync lchown */
r = uv_fs_lchown(NULL, &req, "test_file_link", -1, -1, NULL);
ASSERT(r == 0);
ASSERT(req.result == 0);
uv_fs_req_cleanup(&req);
/* async lchown */
r = uv_fs_lchown(loop, &req, "test_file_link", -1, -1, lchown_cb);
ASSERT(r == 0);
uv_run(loop, UV_RUN_DEFAULT);
ASSERT(lchown_cb_count == 1);
/* Close file */
r = uv_fs_close(NULL, &req, file, NULL);
ASSERT(r == 0);
@ -1581,6 +1608,7 @@ TEST_IMPL(fs_chown) {
/* Cleanup. */
unlink("test_file");
unlink("test_file_link");
MAKE_VALGRIND_HAPPY();
return 0;