From 63263fcdb4c199563e5ff67e9ae531d637a611ad Mon Sep 17 00:00:00 2001 From: gwx1278443 Date: Sat, 7 Oct 2023 15:11:47 +0800 Subject: [PATCH 1/2] renameDir_update Signed-off-by: gwx1278443 --- .../kits/js/src/mod_fs/properties/movedir.cpp | 66 ++++++++++++++----- 1 file changed, 48 insertions(+), 18 deletions(-) diff --git a/interfaces/kits/js/src/mod_fs/properties/movedir.cpp b/interfaces/kits/js/src/mod_fs/properties/movedir.cpp index 6f845c17d..313f38305 100644 --- a/interfaces/kits/js/src/mod_fs/properties/movedir.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/movedir.cpp @@ -35,7 +35,7 @@ using namespace OHOS::FileManagement::LibN; static int RecurMoveDir(const string &srcPath, const string &destPath, const int mode, vector &errfiles); - +static int SetAccessAndModificationTime(const string &path); static tuple JudgeExistAndEmpty(const string &path) { filesystem::path pathName(path); @@ -124,19 +124,9 @@ static int CopyAndDeleteFile(const string &src, const string &dest) HILOGE("Failed to copy file, error code: %{public}d", errCode.value()); return errCode.value(); } - std::unique_ptr utime_req = { - new (std::nothrow) uv_fs_t, CommonFunc::fs_req_cleanup }; - if (!utime_req) { - HILOGE("Failed to request heap memory."); - return ENOMEM; - } - 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; - ret = uv_fs_utime(nullptr, utime_req.get(), dstPath.c_str(), atime, mtime, nullptr); + ret = SetAccessAndModificationTime(dstPath); if (ret < 0) { - HILOGE("Failed to utime dstPath"); + HILOGE("Failed to set time for %s, error code: %d", dstPath.c_str(), ret); return ret; } return RemovePath(src); @@ -169,6 +159,46 @@ static int32_t FilterFunc(const struct dirent *filename) return FILE_MATCH; } +// 封装设置访问时间和修改时间的函数 +static int MoveDir(const string &path) +{ + std::unique_ptr utime_req = { + new (std::nothrow) uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!utime_req) { + HILOGE("Failed to request heap memory."); + return ENOMEM; + } + //创建文件夹 + if(!filesystem::create_directory(destPath, errCode)){ + HILOGE("Failed to create directory, error code: %{public}d", errCode.value()); + return errCode.value(); + } + + //获取指定路径的文件或目录的状态信息 + std::unique_ptr stat_req = { + new (std::nothrow) uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!stat_req) { + HILOGE("Failed to request heap memory."); + return ENOMEM; + } + int ret = uv_fs_stat(nullptr, stat_req.get(), path.c_str(), nullptr); + if (ret < 0) { + HILOGE("Failed to stat srcPath"); + return ret; + } + 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; + ret = uv_fs_utime(nullptr, utime_req.get(), path.c_str(), atime, mtime, nullptr); + if (ret < 0) { + HILOGE("Failed to utime %s, error code: %d", path.c_str(), ret); + return ret; + } + + return ret; +} + static int RenameDir(const string &src, const string &dest, const int mode, vector &errfiles) { filesystem::path destPath(dest); @@ -178,11 +208,11 @@ static int RenameDir(const string &src, const string &dest, const int mode, vect filesystem::rename(srcPath, destPath, errCode); if (errCode.value() == EXDEV) { HILOGE("Failed to rename file due to EXDEV"); - if (filesystem::create_directory(destPath, errCode)) { - return RecurMoveDir(src, dest, mode, errfiles); - } else { - HILOGE("Failed to create directory, error code: %{public}d", errCode.value()); - return errCode.value(); + int ret = MoveDir(destPath); + if (ret < 0){ + HILOGE("Failed to MoveDir_utime %s, error code: %d", path.c_str(), ret); + return ret; + } } } if (errCode.value() != 0) { -- Gitee From ae45a4fd82d440f119c1f0615784185baf58f5b0 Mon Sep 17 00:00:00 2001 From: gwx1278443 Date: Wed, 25 Oct 2023 11:21:37 +0800 Subject: [PATCH 2/2] getrealpath Signed-off-by: gwx1278443 --- interfaces/kits/js/src/mod_fs/common_func.cpp | 41 +++++ interfaces/kits/js/src/mod_fs/common_func.h | 3 + .../kits/js/src/mod_fs/properties/copydir.cpp | 48 ++++-- .../js/src/mod_fs/properties/listfile.cpp | 42 +++-- .../kits/js/src/mod_fs/properties/movedir.cpp | 152 +++++++++--------- 5 files changed, 177 insertions(+), 109 deletions(-) diff --git a/interfaces/kits/js/src/mod_fs/common_func.cpp b/interfaces/kits/js/src/mod_fs/common_func.cpp index 94f4cf5c5..834dc0473 100644 --- a/interfaces/kits/js/src/mod_fs/common_func.cpp +++ b/interfaces/kits/js/src/mod_fs/common_func.cpp @@ -80,6 +80,32 @@ void InitOpenMode(napi_env env, napi_value exports) } } +void InitWhenceType(napi_env env, napi_value exports) +{ + char propertyName[] = "WhenceType"; + napi_property_descriptor desc[] = { + DECLARE_NAPI_STATIC_PROPERTY("SEEK_SET", NVal::CreateInt32(env, SEEK_SET).val_), + DECLARE_NAPI_STATIC_PROPERTY("SEEK_CUR", NVal::CreateInt32(env, SEEK_CUR).val_), + DECLARE_NAPI_STATIC_PROPERTY("SEEK_END", NVal::CreateInt32(env, SEEK_END).val_), + }; + napi_value obj = nullptr; + napi_status status = napi_create_object(env, &obj); + if (status != napi_ok) { + HILOGE("Failed to create object at initializing whenceType"); + return; + } + status = napi_define_properties(env, obj, sizeof(desc) / sizeof(desc[0]), desc); + if (status != napi_ok) { + HILOGE("Failed to set properties of character at initializing whenceType"); + return; + } + status = napi_set_named_property(env, exports, propertyName, obj); + if (status != napi_ok) { + HILOGE("Failed to set direction property at initializing whenceType"); + return; + } +} + static tuple GetActualLen(napi_env env, size_t bufLen, size_t bufOff, NVal op) { bool succ = false; @@ -204,6 +230,21 @@ void CommonFunc::fs_req_cleanup(uv_fs_t* req) } } +tuple> CommonFunc::GetRealPath(const string &path) +{ + std::unique_ptr realpath_req = { + new (std::nothrow) uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!realpath_req) { + HILOGE("Failed to request heap memory."); + return { ENOMEM, move(realpath_req) }; + } + int ret = uv_fs_realpath(nullptr, realpath_req.get(), path.c_str(), nullptr); + if (ret < 0) { + return { ret, move(realpath_req) }; + } + return { ERRNO_NOERR, move(realpath_req) }; +} + string CommonFunc::GetModeFromFlags(unsigned int flags) { const string readMode = "r"; diff --git a/interfaces/kits/js/src/mod_fs/common_func.h b/interfaces/kits/js/src/mod_fs/common_func.h index f332321c1..e2c23b91c 100644 --- a/interfaces/kits/js/src/mod_fs/common_func.h +++ b/interfaces/kits/js/src/mod_fs/common_func.h @@ -53,6 +53,7 @@ struct FileInfo { }; void InitOpenMode(napi_env env, napi_value exports); +void InitWhenceType(napi_env env, napi_value exports); struct CommonFunc { static unsigned int ConvertJsFlags(unsigned int &flags); @@ -71,6 +72,8 @@ struct CommonFunc { napi_value srcPath, napi_value dstPath); static void fs_req_cleanup(uv_fs_t* req); + static std::tuple> + GetRealPath(const std::string &path); static std::string GetModeFromFlags(unsigned int flags); static bool CheckPublicDirPath(const std::string &sandboxPath); static std::string Decode(const std::string &uri); diff --git a/interfaces/kits/js/src/mod_fs/properties/copydir.cpp b/interfaces/kits/js/src/mod_fs/properties/copydir.cpp index 3dcaea202..5db7182df 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copydir.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/copydir.cpp @@ -31,6 +31,7 @@ namespace FileManagement { namespace ModuleFileIO { using namespace std; using namespace OHOS::FileManagement::LibN; +using UvRequest = std::unique_ptr; static int RecurCopyDir(const string &srcPath, const string &destPath, const int mode, vector &errfiles); @@ -44,21 +45,33 @@ static bool AllowToCopy(const string &src, const string &dest) return true; } -static tuple, unique_ptr, int> ParseAndCheckJsOperand(napi_env env, - const NFuncArg &funcArg) +static tuple ParseAndCheckJsOperand(napi_env env, const NFuncArg &funcArg) { + UvRequest realpathSrc = { nullptr, CommonFunc::fs_req_cleanup }; + UvRequest realpathDest = { nullptr, CommonFunc::fs_req_cleanup }; auto [resGetFirstArg, src, ignore] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); if (!resGetFirstArg || !filesystem::is_directory(filesystem::status(src.get()))) { HILOGE("Invalid src"); - return { false, nullptr, nullptr, 0 }; + return { EINVAL, move(realpathSrc), move(realpathDest), 0 }; + } + int ret = 0; + tie(ret, realpathSrc) = CommonFunc::GetRealPath(src.get()); + if (ret) { + HILOGE("Failed to get absolute path from src, ret: %{public}d", ret); + return { ret, move(realpathSrc), move(realpathDest), 0 }; } auto [resGetSecondArg, dest, unused] = NVal(env, funcArg[NARG_POS::SECOND]).ToUTF8String(); if (!resGetSecondArg || !filesystem::is_directory(filesystem::status(dest.get()))) { HILOGE("Invalid dest"); - return { false, nullptr, nullptr, 0 }; + return { EINVAL, move(realpathSrc), move(realpathDest), 0 }; + } + tie(ret, realpathDest) = CommonFunc::GetRealPath(dest.get()); + if (ret) { + HILOGE("Failed to get absolute path from dest, ret: %{public}d", ret); + return { ret, move(realpathSrc), move(realpathDest), 0 }; } - if (!AllowToCopy(src.get(), dest.get())) { - return { false, nullptr, nullptr, 0 }; + if (!AllowToCopy(static_cast(realpathSrc->ptr), static_cast(realpathDest->ptr))) { + return { EINVAL, move(realpathSrc), move(realpathDest), 0 }; } int mode = 0; if (funcArg.GetArgc() >= NARG_CNT::THREE) { @@ -66,10 +79,10 @@ static tuple, unique_ptr, int> ParseAndCheckJsO tie(resGetThirdArg, mode) = NVal(env, funcArg[NARG_POS::THIRD]).ToInt32(mode); if (!resGetThirdArg || (mode < COPYMODE_MIN || mode > COPYMODE_MAX)) { HILOGE("Invalid mode"); - return { false, nullptr, nullptr, 0 }; + return { EINVAL, move(realpathSrc), move(realpathDest), 0 }; } } - return { true, move(src), move(dest), mode }; + return { ERRNO_NOERR, move(realpathSrc), move(realpathDest), mode }; } static int MakeDir(const string &path) @@ -237,14 +250,16 @@ napi_value CopyDir::Sync(napi_env env, napi_callback_info info) NError(EINVAL).ThrowErr(env); return nullptr; } - auto [succ, src, dest, mode] = ParseAndCheckJsOperand(env, funcArg); - if (!succ) { - NError(EINVAL).ThrowErr(env); + auto [ret, srcReq, destReq, mode] = ParseAndCheckJsOperand(env, funcArg); + if (ret) { + NError(ret).ThrowErr(env); return nullptr; } vector errfiles = {}; - int ret = CopyDirFunc(src.get(), dest.get(), mode, errfiles); + string src(static_cast(srcReq->ptr)); + string dest(static_cast(destReq->ptr)); + ret = CopyDirFunc(src, dest, mode, errfiles); if (ret == EEXIST && mode == DIRMODE_FILE_COPY_THROW_ERR) { NError(ret).ThrowErrAddData(env, EEXIST, PushErrFilesInData(env, errfiles)); return nullptr; @@ -268,9 +283,9 @@ napi_value CopyDir::Async(napi_env env, napi_callback_info info) NError(EINVAL).ThrowErr(env); return nullptr; } - auto [succ, src, dest, mode] = ParseAndCheckJsOperand(env, funcArg); - if (!succ) { - NError(EINVAL).ThrowErr(env); + auto [ret, srcReq, destReq, mode] = ParseAndCheckJsOperand(env, funcArg); + if (!ret) { + NError(ret).ThrowErr(env); return nullptr; } @@ -280,7 +295,8 @@ napi_value CopyDir::Async(napi_env env, napi_callback_info info) NError(ENOMEM).ThrowErr(env); return nullptr; } - auto cbExec = [srcPath = string(src.get()), destPath = string(dest.get()), mode = mode, arg]() -> NError { + auto cbExec = [srcPath = string(static_cast(srcReq->ptr)), + destPath = string(static_cast(destReq->ptr)), mode = mode, arg]() -> NError { arg->errNo = CopyDirFunc(srcPath, destPath, mode, arg->errfiles); if (arg->errNo) { return NError(arg->errNo); diff --git a/interfaces/kits/js/src/mod_fs/properties/listfile.cpp b/interfaces/kits/js/src/mod_fs/properties/listfile.cpp index e046e1745..758d69fb6 100755 --- a/interfaces/kits/js/src/mod_fs/properties/listfile.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/listfile.cpp @@ -23,6 +23,7 @@ #include #include +#include "common_func.h" #include "file_utils.h" #include "filemgmt_libhilog.h" @@ -100,14 +101,14 @@ static bool GetFileFilterParam(const NVal &argv, FileFilter *filter) return true; } -static bool GetOptionParam(const NVal &argv, OptionArgs *optionArgs) +static int GetOptionParam(const NVal &argv, OptionArgs *optionArgs) { bool succ = false; if (argv.HasProp("listNum")) { tie(succ, optionArgs->listNum) = argv.GetProp("listNum").ToInt64(0); if (!succ || optionArgs->listNum < 0) { HILOGE("Failed to get listNum prop"); - return false; + return EINVAL; } } @@ -115,7 +116,7 @@ static bool GetOptionParam(const NVal &argv, OptionArgs *optionArgs) tie(succ, optionArgs->recursion) = argv.GetProp("recursion").ToBool(false); if (!succ) { HILOGE("Failed to get recursion prop."); - return false; + return EINVAL; } } @@ -125,28 +126,33 @@ static bool GetOptionParam(const NVal &argv, OptionArgs *optionArgs) auto ret = GetFileFilterParam(filterProp, &optionArgs->filter); if (!ret) { HILOGE("Failed to get filter prop."); - return false; + return EINVAL; } } } - return true; + return ERRNO_NOERR; } -static bool GetOptionArg(napi_env env, const NFuncArg &funcArg, OptionArgs &optionArgs, const string &path) +static int GetOptionArg(napi_env env, const NFuncArg &funcArg, OptionArgs &optionArgs, const string &path) { - optionArgs.path = path; + auto [ret, realpathSrc] = CommonFunc::GetRealPath(path); + if (ret) { + HILOGE("Failed to get absolute path"); + return ret; + } + optionArgs.path = string(static_cast(realpathSrc->ptr)); if (funcArg.GetArgc() == NARG_CNT::ONE) { - return true; + return ERRNO_NOERR; } if (funcArg.GetArgc() >= NARG_CNT::TWO) { auto options = NVal(env, funcArg[NARG_POS::SECOND]); if (options.TypeIs(napi_object)) { return GetOptionParam(options, &optionArgs); } else if (options.TypeIs(napi_undefined) || options.TypeIs(napi_function)) { - return true; + return ERRNO_NOERR; } } - return false; + return EINVAL; } static bool FilterSuffix(const vector &suffixs, const struct dirent &filename) @@ -331,13 +337,14 @@ napi_value ListFile::Sync(napi_env env, napi_callback_info info) NError(EINVAL).ThrowErr(env); return nullptr; } - if (!GetOptionArg(env, funcArg, g_optionArgs, string(path.get()))) { + int ret = GetOptionArg(env, funcArg, g_optionArgs, string(path.get())); + if (ret) { HILOGE("Invalid options"); - NError(EINVAL).ThrowErr(env); + NError(ret).ThrowErr(env); return nullptr; } - vector direntsRes; - int ret = 0; + std::vector direntsRes; + ret = 0; ret = g_optionArgs.recursion ? RecursiveFunc(path.get(), direntsRes) : FilterFileRes(path.get(), direntsRes); if (ret) { NError(ret).ThrowErr(env); @@ -365,9 +372,10 @@ napi_value ListFile::Async(napi_env env, napi_callback_info info) } OptionArgs optionArgsTmp = {}; - if (!GetOptionArg(env, funcArg, optionArgsTmp, string(path.get()))) { - HILOGE("Invalid options"); - NError(EINVAL).ThrowErr(env); + int ret = GetOptionArg(env, funcArg, optionArgsTmp, string(path.get())); + if (ret) { + HILOGE("Failed to get arguments"); + NError(ret).ThrowErr(env); return nullptr; } diff --git a/interfaces/kits/js/src/mod_fs/properties/movedir.cpp b/interfaces/kits/js/src/mod_fs/properties/movedir.cpp index 313f38305..e519a6cba 100644 --- a/interfaces/kits/js/src/mod_fs/properties/movedir.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/movedir.cpp @@ -32,10 +32,11 @@ namespace FileManagement { namespace ModuleFileIO { using namespace std; using namespace OHOS::FileManagement::LibN; +using UvRequest = std::unique_ptr; static int RecurMoveDir(const string &srcPath, const string &destPath, const int mode, vector &errfiles); -static int SetAccessAndModificationTime(const string &path); + static tuple JudgeExistAndEmpty(const string &path) { filesystem::path pathName(path); @@ -73,17 +74,30 @@ static int RemovePath(const string& pathStr) return ERRNO_NOERR; } -static tuple, unique_ptr, int> ParseJsOperand(napi_env env, const NFuncArg& funcArg) +static tuple ParseJsOperand(napi_env env, const NFuncArg& funcArg) { + UvRequest realpathSrc = { nullptr, CommonFunc::fs_req_cleanup }; + UvRequest realpathDest = { nullptr, CommonFunc::fs_req_cleanup }; auto [resGetFirstArg, src, ignore] = NVal(env, funcArg[NARG_POS::FIRST]).ToUTF8String(); if (!resGetFirstArg || !filesystem::is_directory(filesystem::status(src.get()))) { HILOGE("Invalid src"); - return { false, nullptr, nullptr, 0 }; + return { ENOENT, move(realpathSrc), move(realpathDest), 0 }; + } + int ret = 0; + tie(ret, realpathSrc) = CommonFunc::GetRealPath(src.get()); + if (ret) { + HILOGE("Failed to get absolute path from src, ret: %{public}d", ret); + return { ret, move(realpathSrc), move(realpathDest), 0 }; } auto [resGetSecondArg, dest, unused] = NVal(env, funcArg[NARG_POS::SECOND]).ToUTF8String(); if (!resGetSecondArg || !filesystem::is_directory(filesystem::status(dest.get()))) { HILOGE("Invalid dest"); - return { false, nullptr, nullptr, 0 }; + return { ENOENT, move(realpathSrc), move(realpathDest), 0 }; + } + tie(ret, realpathDest) = CommonFunc::GetRealPath(dest.get()); + if (ret) { + HILOGE("Failed to get absolute path from dest, ret: %{public}d", ret); + return { ret, move(realpathSrc), move(realpathDest), 0 }; } int mode = 0; if (funcArg.GetArgc() >= NARG_CNT::THREE) { @@ -91,13 +105,13 @@ static tuple, unique_ptr, int> ParseJsOperand(n tie(resGetThirdArg, mode) = NVal(env, funcArg[NARG_POS::THIRD]).ToInt32(mode); if (!resGetThirdArg || (mode < DIRMODE_MIN || mode > DIRMODE_MAX)) { HILOGE("Invalid mode"); - return { false, nullptr, nullptr, 0 }; + return { EINVAL, move(realpathSrc), move(realpathDest), 0 }; } } - return { true, move(src), move(dest), mode }; + return { ERRNO_NOERR, move(realpathSrc), move(realpathDest), mode }; } -static int CopyAndDeleteFile(const string &src, const string &dest) +static int RestoreTime(const string &srcPath, const string &destPath) { std::unique_ptr stat_req = { new (std::nothrow) uv_fs_t, CommonFunc::fs_req_cleanup }; @@ -105,11 +119,31 @@ static int CopyAndDeleteFile(const string &src, const string &dest) HILOGE("Failed to request heap memory."); return ENOMEM; } - int ret = uv_fs_stat(nullptr, stat_req.get(), src.c_str(), nullptr); + int ret = uv_fs_stat(nullptr, stat_req.get(), srcPath.c_str(), nullptr); if (ret < 0) { HILOGE("Failed to stat srcPath"); return ret; } + 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) { + 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; +} + +static int CopyAndDeleteFile(const string &src, const string &dest) +{ filesystem::path dstPath(dest); if (filesystem::exists(dstPath)) { int removeRes = RemovePath(dest); @@ -124,9 +158,9 @@ static int CopyAndDeleteFile(const string &src, const string &dest) HILOGE("Failed to copy file, error code: %{public}d", errCode.value()); return errCode.value(); } - ret = SetAccessAndModificationTime(dstPath); - if (ret < 0) { - HILOGE("Failed to set time for %s, error code: %d", dstPath.c_str(), ret); + int ret = RestoreTime(srcPath, dstPath); + if (ret) { + HILOGE("Failed to utime dstPath"); return ret; } return RemovePath(src); @@ -159,69 +193,33 @@ static int32_t FilterFunc(const struct dirent *filename) return FILE_MATCH; } -// 封装设置访问时间和修改时间的函数 -static int MoveDir(const string &path) -{ - std::unique_ptr utime_req = { - new (std::nothrow) uv_fs_t, CommonFunc::fs_req_cleanup }; - if (!utime_req) { - HILOGE("Failed to request heap memory."); - return ENOMEM; - } - //创建文件夹 - if(!filesystem::create_directory(destPath, errCode)){ - HILOGE("Failed to create directory, error code: %{public}d", errCode.value()); - return errCode.value(); - } - - //获取指定路径的文件或目录的状态信息 - std::unique_ptr stat_req = { - new (std::nothrow) uv_fs_t, CommonFunc::fs_req_cleanup }; - if (!stat_req) { - HILOGE("Failed to request heap memory."); - return ENOMEM; - } - int ret = uv_fs_stat(nullptr, stat_req.get(), path.c_str(), nullptr); - if (ret < 0) { - HILOGE("Failed to stat srcPath"); - return ret; - } - 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; - ret = uv_fs_utime(nullptr, utime_req.get(), path.c_str(), atime, mtime, nullptr); - if (ret < 0) { - HILOGE("Failed to utime %s, error code: %d", path.c_str(), ret); - return ret; - } - - return ret; -} - static int RenameDir(const string &src, const string &dest, const int mode, vector &errfiles) { filesystem::path destPath(dest); - if (!filesystem::exists(destPath)) { - filesystem::path srcPath(src); - std::error_code errCode; - filesystem::rename(srcPath, destPath, errCode); - if (errCode.value() == EXDEV) { - HILOGE("Failed to rename file due to EXDEV"); - int ret = MoveDir(destPath); - if (ret < 0){ - HILOGE("Failed to MoveDir_utime %s, error code: %d", path.c_str(), ret); - return ret; - } - } - } - if (errCode.value() != 0) { - HILOGE("Failed to rename file, error code: %{public}d", errCode.value()); + if (filesystem::exists(destPath)) { + return RecurMoveDir(src, dest, mode, errfiles); + } + filesystem::path srcPath(src); + std::error_code errCode; + filesystem::rename(srcPath, destPath, errCode); + if (errCode.value() == EXDEV) { + HILOGE("Failed to rename file due to EXDEV"); + if (!filesystem::create_directory(destPath, errCode)) { + HILOGE("Failed to create directory, error code: %{public}d", errCode.value()); return errCode.value(); } - } else { + + int ret = RestoreTime(srcPath, destPath); + if (ret) { + HILOGE("Failed to utime dstPath"); + return ret; + } return RecurMoveDir(src, dest, mode, errfiles); } + if (errCode.value() != 0) { + HILOGE("Failed to rename file, error code: %{public}d", errCode.value()); + return errCode.value(); + } return ERRNO_NOERR; } @@ -353,14 +351,15 @@ napi_value MoveDir::Sync(napi_env env, napi_callback_info info) NError(EINVAL).ThrowErr(env); return nullptr; } - auto [succ, src, dest, mode] = ParseJsOperand(env, funcArg); - if (!succ) { - NError(EINVAL).ThrowErr(env); - return nullptr; + auto [ret, srcReq, destReq, mode] = ParseJsOperand(env, funcArg); + if (ret) { + NError(ret).ThrowErr(env); } + string src(static_cast(srcReq->ptr)); + string dest(static_cast(destReq->ptr)); vector errfiles = {}; - int ret = MoveDirFunc(src.get(), dest.get(), mode, errfiles); + ret = MoveDirFunc(src, dest, mode, errfiles); if (ret == EEXIST && mode == DIRMODE_FILE_THROW_ERR) { NError(ret).ThrowErrAddData(env, EEXIST, GetErrData(env, errfiles)); return nullptr; @@ -385,9 +384,9 @@ napi_value MoveDir::Async(napi_env env, napi_callback_info info) NError(EINVAL).ThrowErr(env); return nullptr; } - auto [succ, src, dest, mode] = ParseJsOperand(env, funcArg); - if (!succ) { - NError(EINVAL).ThrowErr(env); + auto [ret, srcReq, destReq, mode] = ParseJsOperand(env, funcArg); + if (ret) { + NError(ret).ThrowErr(env); return nullptr; } auto arg = CreateSharedPtr(); @@ -396,7 +395,8 @@ napi_value MoveDir::Async(napi_env env, napi_callback_info info) NError(ENOMEM).ThrowErr(env); return nullptr; } - auto cbExec = [srcPath = string(src.get()), destPath = string(dest.get()), mode = mode, arg]() -> NError { + auto cbExec = [srcPath = string(static_cast(srcReq->ptr)), + destPath = string(static_cast(destReq->ptr)), mode = mode, arg]() -> NError { arg->errNo = MoveDirFunc(srcPath, destPath, mode, arg->errfiles); if (arg->errNo) { return NError(arg->errNo); -- Gitee