From 7800f2437d904c4f47254cb1dd891c7a5be3c17c Mon Sep 17 00:00:00 2001 From: fengjq Date: Sun, 3 Dec 2023 17:51:43 +0800 Subject: [PATCH] Bugfix for moveDir, recover mtime for dest/src Signed-off-by: fengjq --- .../kits/js/src/mod_fs/properties/move.cpp | 74 ++++++++++----- .../kits/js/src/mod_fs/properties/movedir.cpp | 89 ++++++++++++------- 2 files changed, 105 insertions(+), 58 deletions(-) diff --git a/interfaces/kits/js/src/mod_fs/properties/move.cpp b/interfaces/kits/js/src/mod_fs/properties/move.cpp index 38a4812fc..2ee03a519 100644 --- a/interfaces/kits/js/src/mod_fs/properties/move.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/move.cpp @@ -94,32 +94,50 @@ static int ChangeTime(const string &path, uv_fs_t *stat_req) double mtime = static_cast(stat_req->statbuf.st_mtim.tv_sec) + static_cast(stat_req->statbuf.st_mtim.tv_nsec) / NS; int ret = uv_fs_utime(nullptr, utime_req.get(), path.c_str(), atime, mtime, nullptr); - if (ret < 0) { - HILOGE("Failed to utime dstPath"); - } return ret; } -static int CopyAndDeleteFile(const string &src, const string &dest) + +static tuple IsFileAccess(const string &path) { - std::unique_ptr stat_req = { - new (std::nothrow) uv_fs_t, CommonFunc::fs_req_cleanup }; - if (!stat_req) { + std::unique_ptr access_req = { + new uv_fs_t, CommonFunc::fs_req_cleanup }; + if (access_req == nullptr) { HILOGE("Failed to request heap memory."); - return ENOMEM; + return { ENOMEM, false }; } - int ret = uv_fs_stat(nullptr, stat_req.get(), src.c_str(), nullptr); - if (ret < 0) { - HILOGE("Failed to stat srcPath"); + int ret = uv_fs_access(nullptr, access_req.get(), path.c_str(), 0, nullptr); + if (ret < 0 && ret != -ENOENT) { + HILOGE("Failed to access file by path, error: %{public}d", ret); + return { ret, false }; + } + bool isExist = (ret == ERRNO_NOERR); + return { ERRNO_NOERR, isExist }; +} + +static tuple> GetStat(const string &path) +{ + unique_ptr stat_req = { + new (nothrow) uv_fs_t, CommonFunc::fs_req_cleanup }; + if (stat_req == nullptr) { + HILOGE("Failed to request heap memory."); + return { ENOMEM, move(stat_req) }; + } + int ret = uv_fs_stat(nullptr, stat_req.get(), path.c_str(), nullptr); + return { ret, move(stat_req) }; +} + +static int CopyAndDeleteFile(const string &src, const string &dest) +{ + auto [ret, isExist] = IsFileAccess(dest); + if (ret != ERRNO_NOERR) { return ret; } #if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM) filesystem::path dstPath(dest); std::error_code errCode; - if (filesystem::exists(dstPath)) { - if (!filesystem::remove(dstPath, errCode)) { - HILOGE("Failed to remove dest file, error code: %{public}d", errCode.value()); - return errCode.value(); - } + if (isExist && !filesystem::remove(dstPath, errCode)) { + HILOGE("Failed to remove dest file, error code: %{public}d", errCode.value()); + return errCode.value(); } filesystem::path srcPath(src); if (!filesystem::copy_file(srcPath, dstPath, filesystem::copy_options::overwrite_existing, errCode)) { @@ -135,20 +153,28 @@ static int CopyAndDeleteFile(const string &src, const string &dest) return ret; } #endif + if (!isExist) { + auto [resGetStat, statReq] = GetStat(src); + if (resGetStat != ERRNO_NOERR) { + HILOGE("Failed to get time of file, error: %{public}d", resGetStat); + return resGetStat; + } + ret = ChangeTime(dest, statReq.get()); + if (ret != ERRNO_NOERR) { + HILOGE("Failed to change mtime and ctime for dest, error: %{public}d", ret); + } + } uv_fs_t unlink_req; ret = uv_fs_unlink(nullptr, &unlink_req, src.c_str(), nullptr); if (ret < 0) { - HILOGE("Failed to unlink src file"); - int result = uv_fs_unlink(nullptr, &unlink_req, dest.c_str(), nullptr); - if (result < 0) { - HILOGE("Failed to unlink dest file"); - return result; + HILOGE("Failed to unlink src file, error: %{public}d", ret); + ret = uv_fs_unlink(nullptr, &unlink_req, dest.c_str(), nullptr); + if (ret < 0) { + HILOGE("Failed to unlink dest file, error: %{public}d", ret); } - uv_fs_req_cleanup(&unlink_req); - return ret; } uv_fs_req_cleanup(&unlink_req); - return ChangeTime(dest, stat_req.get()); + return ret; } static int RenameFile(const string &src, const string &dest) diff --git a/interfaces/kits/js/src/mod_fs/properties/movedir.cpp b/interfaces/kits/js/src/mod_fs/properties/movedir.cpp index 57ffb70fe..6fa70de83 100644 --- a/interfaces/kits/js/src/mod_fs/properties/movedir.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/movedir.cpp @@ -97,41 +97,50 @@ static tuple, unique_ptr, int> ParseJsOperand(n return { true, move(src), move(dest), mode }; } -static int RestoreTime(const string &srcPath, const string &destPath) +static tuple> GetStat(const string &path) { - std::unique_ptr stat_req = { - new (std::nothrow) uv_fs_t, CommonFunc::fs_req_cleanup }; - if (!stat_req) { + unique_ptr stat_req = { + new (nothrow) uv_fs_t, CommonFunc::fs_req_cleanup }; + if (stat_req == nullptr) { HILOGE("Failed to request heap memory."); - return ENOMEM; - } - int ret = uv_fs_stat(nullptr, stat_req.get(), srcPath.c_str(), nullptr); - if (ret < 0) { - HILOGE("Failed to stat srcPath"); - return ret; + return { ENOMEM, move(stat_req) }; } - double atime = static_cast(stat_req->statbuf.st_atim.tv_sec) + - static_cast(stat_req->statbuf.st_atim.tv_nsec) / NS; - double mtime = static_cast(stat_req->statbuf.st_mtim.tv_sec) + - static_cast(stat_req->statbuf.st_mtim.tv_nsec) / NS; - std::unique_ptr utime_req = { - new (std::nothrow) uv_fs_t, CommonFunc::fs_req_cleanup }; - if (!utime_req) { + int ret = uv_fs_stat(nullptr, stat_req.get(), path.c_str(), nullptr); + return { ret, move(stat_req) }; +} + +static tuple GetFileTime(const string &src) +{ + auto [ret, statReq] = GetStat(src); + if (ret != ERRNO_NOERR) { + HILOGE("Failed to get file stat, error: %{public}d", ret); + return { 0, 0, ret }; + } + double atime = static_cast(statReq->statbuf.st_atim.tv_sec) + + static_cast(statReq->statbuf.st_atim.tv_nsec) / NS; + double mtime = static_cast(statReq->statbuf.st_mtim.tv_sec) + + static_cast(statReq->statbuf.st_mtim.tv_nsec) / NS; + + return { ERRNO_NOERR, atime, mtime }; +} + +static int SetFileTime(const string &dest, double atime, double mtime) +{ + unique_ptr utime_req = { + new (nothrow) uv_fs_t, CommonFunc::fs_req_cleanup }; + if (utime_req == nullptr) { HILOGE("Failed to request heap memory."); return ENOMEM; } - ret = uv_fs_utime(nullptr, utime_req.get(), destPath.c_str(), atime, mtime, nullptr); - if (ret < 0) { - HILOGE("Failed to utime %s, error code: %d", destPath.c_str(), ret); - return ret; - } - return ERRNO_NOERR; + int ret = uv_fs_utime(nullptr, utime_req.get(), dest.c_str(), atime, mtime, nullptr); + return ret; } static int CopyAndDeleteFile(const string &src, const string &dest) { filesystem::path dstPath(dest); - if (filesystem::exists(dstPath)) { + bool isExist = filesystem::exists(dstPath); + if (isExist) { int removeRes = RemovePath(dest); if (removeRes != 0) { HILOGE("Failed to remove dest file"); @@ -144,10 +153,16 @@ static int CopyAndDeleteFile(const string &src, const string &dest) HILOGE("Failed to copy file, error code: %{public}d", errCode.value()); return errCode.value(); } - int ret = RestoreTime(srcPath, dstPath); - if (ret) { - HILOGE("Failed to utime dstPath"); - return ret; + if (!isExist) { + auto [ret, atime, mtime] = GetFileTime(src); + if (ret != ERRNO_NOERR) { + HILOGE("Failed to get time of file, error: %{public}d", ret); + return ret; + } + ret = SetFileTime(dest, atime, mtime); + if (ret != ERRNO_NOERR) { + HILOGE("Failed to change mtime and ctime for dest, error: %{public}d", ret); + } } return RemovePath(src); } @@ -189,6 +204,11 @@ static int RenameDir(const string &src, const string &dest, const int mode, dequ if (filesystem::exists(destPath)) { return RecurMoveDir(src, dest, mode, errfiles); } + auto [ret, atime, mtime] = GetFileTime(src); + if (ret != ERRNO_NOERR) { + HILOGE("Failed to get stat of src, error: %{public}d", ret); + return ret; + } filesystem::path srcPath(src); std::error_code errCode; filesystem::rename(srcPath, destPath, errCode); @@ -198,17 +218,18 @@ static int RenameDir(const string &src, const string &dest, const int mode, dequ HILOGE("Failed to create directory, error code: %{public}d", errCode.value()); return errCode.value(); } - int ret = RestoreTime(srcPath, destPath); - if (ret) { - HILOGE("Failed to utime dstPath"); + int ret = RecurMoveDir(src, dest, mode, errfiles); + if (ret != ERRNO_NOERR) { return ret; } - return RecurMoveDir(src, dest, mode, errfiles); - } - if (errCode.value() != 0) { + } else if (errCode.value() != 0) { HILOGE("Failed to rename file, error code: %{public}d", errCode.value()); return errCode.value(); } + ret = SetFileTime(dest, atime, mtime); + if (ret != ERRNO_NOERR) { + HILOGE("Failed to change mtime and ctime for dest after renameDir, error: %{public}d", ret); + } return ERRNO_NOERR; } -- Gitee