linux,darwin: make uv_fs_copyfile behaves like cp -r (#4396)
This commit changes the timestamps in the file, the ownership and the group. Fixes: https://github.com/libuv/libuv/issues/3125 Signed-off-by: Juan José Arboleda <soyjuanarbol@gmail.com>
This commit is contained in:
parent
520eb622f0
commit
bf61390769
@ -1233,6 +1233,7 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) {
|
|||||||
uv_file dstfd;
|
uv_file dstfd;
|
||||||
struct stat src_statsbuf;
|
struct stat src_statsbuf;
|
||||||
struct stat dst_statsbuf;
|
struct stat dst_statsbuf;
|
||||||
|
struct timespec times[2];
|
||||||
int dst_flags;
|
int dst_flags;
|
||||||
int result;
|
int result;
|
||||||
int err;
|
int err;
|
||||||
@ -1310,6 +1311,29 @@ static ssize_t uv__fs_copyfile(uv_fs_t* req) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change the timestamps of the destination file to match the source file.
|
||||||
|
*/
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
times[0] = src_statsbuf.st_atimespec;
|
||||||
|
times[1] = src_statsbuf.st_mtimespec;
|
||||||
|
#else
|
||||||
|
times[0] = src_statsbuf.st_atim;
|
||||||
|
times[1] = src_statsbuf.st_mtim;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (futimens(dstfd, times) == -1) {
|
||||||
|
err = UV__ERR(errno);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Change the ownership and permissions of the destination file to match the
|
||||||
|
* source file.
|
||||||
|
* `cp -p` does not care about errors here, so we don't either.
|
||||||
|
*/
|
||||||
|
fchown(dstfd, src_statsbuf.st_uid, src_statsbuf.st_gid);
|
||||||
|
|
||||||
if (fchmod(dstfd, src_statsbuf.st_mode) == -1) {
|
if (fchmod(dstfd, src_statsbuf.st_mode) == -1) {
|
||||||
err = UV__ERR(errno);
|
err = UV__ERR(errno);
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
|
|||||||
@ -46,6 +46,8 @@ static void handle_result(uv_fs_t* req) {
|
|||||||
uv_fs_t stat_req;
|
uv_fs_t stat_req;
|
||||||
uint64_t size;
|
uint64_t size;
|
||||||
uint64_t mode;
|
uint64_t mode;
|
||||||
|
uint64_t uid;
|
||||||
|
uint64_t gid;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
ASSERT_EQ(req->fs_type, UV_FS_COPYFILE);
|
ASSERT_EQ(req->fs_type, UV_FS_COPYFILE);
|
||||||
@ -56,11 +58,15 @@ static void handle_result(uv_fs_t* req) {
|
|||||||
ASSERT_OK(r);
|
ASSERT_OK(r);
|
||||||
size = stat_req.statbuf.st_size;
|
size = stat_req.statbuf.st_size;
|
||||||
mode = stat_req.statbuf.st_mode;
|
mode = stat_req.statbuf.st_mode;
|
||||||
|
uid = stat_req.statbuf.st_uid;
|
||||||
|
gid = stat_req.statbuf.st_gid;
|
||||||
uv_fs_req_cleanup(&stat_req);
|
uv_fs_req_cleanup(&stat_req);
|
||||||
r = uv_fs_stat(NULL, &stat_req, dst, NULL);
|
r = uv_fs_stat(NULL, &stat_req, dst, NULL);
|
||||||
ASSERT_OK(r);
|
ASSERT_OK(r);
|
||||||
ASSERT_EQ(stat_req.statbuf.st_size, size);
|
ASSERT_EQ(stat_req.statbuf.st_size, size);
|
||||||
ASSERT_EQ(stat_req.statbuf.st_mode, mode);
|
ASSERT_EQ(stat_req.statbuf.st_mode, mode);
|
||||||
|
ASSERT_EQ(stat_req.statbuf.st_uid, uid);
|
||||||
|
ASSERT_EQ(stat_req.statbuf.st_gid, gid);
|
||||||
uv_fs_req_cleanup(&stat_req);
|
uv_fs_req_cleanup(&stat_req);
|
||||||
uv_fs_req_cleanup(req);
|
uv_fs_req_cleanup(req);
|
||||||
result_check_count++;
|
result_check_count++;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user