From d9843a4906f347d700eaa09945486e3256ec8630 Mon Sep 17 00:00:00 2001 From: fengjunqing Date: Wed, 19 Jul 2023 12:17:39 +0800 Subject: [PATCH] Modify moveDir interface; Create directories in crossing device. Signed-off-by: fengjunqing --- .../js/src/mod_fs/properties/copy_file.cpp | 13 +- .../kits/js/src/mod_fs/properties/copydir.cpp | 85 +++++---- .../kits/js/src/mod_fs/properties/move.cpp | 10 ++ .../kits/js/src/mod_fs/properties/movedir.cpp | 169 +++++++++--------- .../kits/js/src/mod_fs/properties/movedir.h | 1 + 5 files changed, 146 insertions(+), 132 deletions(-) mode change 100755 => 100644 interfaces/kits/js/src/mod_fs/properties/copy_file.cpp mode change 100755 => 100644 interfaces/kits/js/src/mod_fs/properties/copydir.cpp mode change 100755 => 100644 interfaces/kits/js/src/mod_fs/properties/movedir.cpp diff --git a/interfaces/kits/js/src/mod_fs/properties/copy_file.cpp b/interfaces/kits/js/src/mod_fs/properties/copy_file.cpp old mode 100755 new mode 100644 index 15eb6ea4b..97ba9ff71 --- a/interfaces/kits/js/src/mod_fs/properties/copy_file.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/copy_file.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -34,6 +35,15 @@ using namespace OHOS::FileManagement::LibN; static NError IsAllPath(FileInfo& srcFile, FileInfo& destFile) { +#if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM) + filesystem::path srcPath(string(srcFile.path.get())); + filesystem::path dstPath(string(destFile.path.get())); + error_code errCode; + if (!filesystem::copy_file(srcPath, dstPath, filesystem::copy_options::overwrite_existing, errCode)) { + HILOGE("Failed to copy file, error code: %{public}d", errCode.value()); + return NError(errCode.value()); + } +#else std::unique_ptr copyfile_req = { new (nothrow) uv_fs_t, CommonFunc::fs_req_cleanup }; if (!copyfile_req) { @@ -44,8 +54,9 @@ static NError IsAllPath(FileInfo& srcFile, FileInfo& destFile) UV_FS_COPYFILE_FICLONE, nullptr); if (ret < 0) { HILOGE("Failed to copy file when all parameters are paths"); - return NError(errno); + return NError(ret); } +#endif return NError(ERRNO_NOERR); } diff --git a/interfaces/kits/js/src/mod_fs/properties/copydir.cpp b/interfaces/kits/js/src/mod_fs/properties/copydir.cpp old mode 100755 new mode 100644 index 16329aff9..3dcaea202 --- a/interfaces/kits/js/src/mod_fs/properties/copydir.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/copydir.cpp @@ -25,7 +25,6 @@ #include "common_func.h" #include "file_utils.h" #include "filemgmt_libhilog.h" -#include "uv.h" namespace OHOS { namespace FileManagement { @@ -33,7 +32,8 @@ namespace ModuleFileIO { using namespace std; using namespace OHOS::FileManagement::LibN; -static int RecurCopyDir(const string &srcPath, const string &destPath, vector &errfiles); +static int RecurCopyDir(const string &srcPath, const string &destPath, const int mode, + vector &errfiles); static bool AllowToCopy(const string &src, const string &dest) { @@ -74,16 +74,11 @@ static tuple, unique_ptr, int> ParseAndCheckJsO static int MakeDir(const string &path) { - std::unique_ptr mkdir_req = { - new (nothrow) uv_fs_t, CommonFunc::fs_req_cleanup }; - if (mkdir_req == nullptr) { - HILOGE("Failed to request heap memory."); - return ENOMEM; - } - int ret = uv_fs_mkdir(nullptr, mkdir_req.get(), path.c_str(), COPYDIR_DEFAULT_PERM, nullptr); - if (ret != 0) { - HILOGE("Failed to create directory"); - return ret; + filesystem::path destDir(path); + std::error_code errCode; + if (!filesystem::create_directory(destDir, errCode)) { + HILOGE("Failed to create directory, error code: %{public}d", errCode.value()); + return errCode.value(); } return ERRNO_NOERR; } @@ -93,6 +88,17 @@ struct NameList { int direntNum = 0; }; +static int RemoveFile(const string& destPath) +{ + filesystem::path destFile(destPath); + std::error_code errCode; + if (!filesystem::remove(destFile, errCode)) { + HILOGE("Failed to remove file with path, error code: %{public}d", errCode.value()); + return errCode.value(); + } + return ERRNO_NOERR; +} + static void Deleter(struct NameList *arg) { for (int i = 0; i < arg->direntNum; i++) { @@ -102,29 +108,27 @@ static void Deleter(struct NameList *arg) free(arg->namelist); } -static int CopyFile(const string &src, const string &dest) +static int CopyFile(const string &src, const string &dest, const int mode) { - if (filesystem::exists(dest)) { - HILOGE("Failed to copy file due to existing destPath with throw err"); - return EEXIST; - } - std::unique_ptr copyfile_req = { - new (nothrow) uv_fs_t, CommonFunc::fs_req_cleanup }; - if (copyfile_req == nullptr) { - HILOGE("Failed to request heap memory."); - return ENOMEM; + filesystem::path dstPath(dest); + if (filesystem::exists(dstPath)) { + int ret = (mode == DIRMODE_FILE_COPY_THROW_ERR) ? EEXIST : RemoveFile(dest); + if (ret) { + HILOGE("Failed to copy file due to existing destPath with throw err"); + return ret; + } } - - int ret = uv_fs_copyfile(nullptr, copyfile_req.get(), src.c_str(), dest.c_str(), - UV_FS_COPYFILE_EXCL, nullptr); - if (ret < 0) { - HILOGE("Failed to move file using copyfile interface"); - return -ret; + filesystem::path srcPath(src); + std::error_code errCode; + if (!filesystem::copy_file(srcPath, dstPath, filesystem::copy_options::overwrite_existing, errCode)) { + HILOGE("Failed to copy file, error code: %{public}d", errCode.value()); + return errCode.value(); } return ERRNO_NOERR; } -static int CopySubDir(const string &srcPath, const string &destPath, vector &errfiles) +static int CopySubDir(const string &srcPath, const string &destPath, const int mode, + vector &errfiles) { if (!filesystem::exists(destPath)) { int res = MakeDir(destPath); @@ -133,7 +137,7 @@ static int CopySubDir(const string &srcPath, const string &destPath, vector &errfiles) +static int RecurCopyDir(const string &srcPath, const string &destPath, const int mode, + vector &errfiles) { unique_ptr pNameList = {new (nothrow) struct NameList, Deleter}; if (pNameList == nullptr) { @@ -158,7 +163,7 @@ static int RecurCopyDir(const string &srcPath, const string &destPath, vectornamelist[i])->d_type == DT_DIR) { string srcTemp = srcPath + '/' + string((pNameList->namelist[i])->d_name); string destTemp = destPath + '/' + string((pNameList->namelist[i])->d_name); - int res = CopySubDir(srcTemp, destTemp, errfiles); + int res = CopySubDir(srcTemp, destTemp, mode, errfiles); if (res == ERRNO_NOERR) { continue; } @@ -166,14 +171,14 @@ static int RecurCopyDir(const string &srcPath, const string &destPath, vectornamelist[i])->d_name); string dest = destPath + '/' + string((pNameList->namelist[i])->d_name); - int res = CopyFile(src, dest); + int res = CopyFile(src, dest, mode); if (res == EEXIST) { errfiles.emplace_back(src, dest); continue; } else if (res == ERRNO_NOERR) { continue; } else { - HILOGE("Failed to copy file"); + HILOGE("Failed to copy file for error %{public}d", res); return res; } } @@ -196,17 +201,7 @@ static int CopyDirFunc(const string &src, const string &dest, const int mode, ve return res; } } - if (mode == DIRMODE_FILE_COPY_REPLACE) { - std::error_code error_code; - filesystem::copy(src, destStr, filesystem::copy_options::overwrite_existing | - filesystem::copy_options::recursive, error_code); - if (error_code.value() != ERRNO_NOERR) { - HILOGE("Failed to copy file"); - return error_code.value(); - } - return ERRNO_NOERR; - } - int res = RecurCopyDir(src, destStr, errfiles); + int res = RecurCopyDir(src, destStr, mode, errfiles); if (!errfiles.empty() && res == ERRNO_NOERR) { return EEXIST; } diff --git a/interfaces/kits/js/src/mod_fs/properties/move.cpp b/interfaces/kits/js/src/mod_fs/properties/move.cpp index e66fab2a7..d03b72ebd 100644 --- a/interfaces/kits/js/src/mod_fs/properties/move.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/move.cpp @@ -84,6 +84,15 @@ static tuple, unique_ptr, int> ParseJsOperand(n static int CopyAndDeleteFile(const string &src, const string &dest) { int ret = 0; +#if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM) + filesystem::path srcPath(src); + filesystem::path dstPath(dest); + error_code errCode; + if (!filesystem::copy_file(srcPath, dstPath, filesystem::copy_options::overwrite_existing, errCode)) { + HILOGE("Failed to copy file, error code: %{public}d", errCode.value()); + return errCode.value(); + } +#else uv_fs_t copyfile_req; ret = uv_fs_copyfile(nullptr, ©file_req, src.c_str(), dest.c_str(), MODE_FORCE_MOVE, nullptr); uv_fs_req_cleanup(©file_req); @@ -91,6 +100,7 @@ static int CopyAndDeleteFile(const string &src, const string &dest) HILOGE("Failed to move file using copyfile interface."); return ret; } +#endif uv_fs_t unlink_req; ret = uv_fs_unlink(nullptr, &unlink_req, src.c_str(), nullptr); if (ret < 0) { diff --git a/interfaces/kits/js/src/mod_fs/properties/movedir.cpp b/interfaces/kits/js/src/mod_fs/properties/movedir.cpp old mode 100755 new mode 100644 index 195aa0e29..42f89e8d9 --- a/interfaces/kits/js/src/mod_fs/properties/movedir.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/movedir.cpp @@ -26,7 +26,6 @@ #include "common_func.h" #include "file_utils.h" #include "filemgmt_libhilog.h" -#include "uv.h" namespace OHOS { namespace FileManagement { @@ -37,27 +36,29 @@ using namespace OHOS::FileManagement::LibN; static int RecurMoveDir(const string &srcPath, const string &destPath, const int mode, vector &errfiles); -static tuple JudgeExistAndEmpty(const string &path) +static int RmDirectory(const string &path) { filesystem::path pathName(path); if (filesystem::exists(pathName)) { - if (filesystem::is_empty(pathName)) { - return { true, true }; + std::error_code errCode; + (void)filesystem::remove_all(pathName, errCode); + if (errCode.value() != 0) { + HILOGE("Failed to remove directory, error code: %{public}d", errCode.value()); + return errCode.value(); } - return { true, false }; } - return { false, false }; + return ERRNO_NOERR; } -static bool RmDirectory(const string &path) +static int RemovePath(const string& pathStr) { - filesystem::path pathName(path); - uintmax_t num = filesystem::remove_all(pathName); - if (!num || filesystem::exists(pathName)) { - HILOGE("Failed to rmdir path"); - return false; + filesystem::path pathTarget(pathStr); + std::error_code errCode; + if (!filesystem::remove(pathTarget, errCode)) { + HILOGE("Failed to remove file or directory, error code: %{public}d", errCode.value()); + return errCode.value(); } - return true; + return ERRNO_NOERR; } static tuple, unique_ptr, int> ParseJsOperand(napi_env env, const NFuncArg& funcArg) @@ -86,49 +87,40 @@ static tuple, unique_ptr, int> ParseJsOperand(n static int CopyAndDeleteFile(const string &src, const string &dest) { - uv_fs_t copyfile_req; - int ret = uv_fs_copyfile(nullptr, ©file_req, src.c_str(), dest.c_str(), UV_FS_COPYFILE_FICLONE_FORCE, nullptr); - if (ret < 0) { - HILOGE("Failed to move file using copyfile interface"); - return -ret; - } - uv_fs_req_cleanup(©file_req); - uv_fs_t unlink_req; - int unlinkSrcRes = uv_fs_unlink(nullptr, &unlink_req, src.c_str(), nullptr); - if (unlinkSrcRes < 0) { - HILOGE("Failed to unlink src file because errno number is: %{public}d", unlinkSrcRes); - int unlinkDestRes = uv_fs_unlink(nullptr, &unlink_req, dest.c_str(), nullptr); - if (unlinkDestRes < 0) { - HILOGE("Failed to unlink dest file because errno number is: %{public}d", unlinkDestRes); + filesystem::path dstPath(dest); + if (filesystem::exists(dstPath)) { + int removeRes = RemovePath(dest); + if (removeRes != 0) { + HILOGE("Failed to remove dest file"); + return removeRes; } - uv_fs_req_cleanup(&unlink_req); - return -unlinkSrcRes; } - uv_fs_req_cleanup(&unlink_req); - return ERRNO_NOERR; + filesystem::path srcPath(src); + std::error_code errCode; + if (!filesystem::copy_file(srcPath, dstPath, filesystem::copy_options::overwrite_existing, errCode)) { + HILOGE("Failed to copy file, error code: %{public}d", errCode.value()); + return errCode.value(); + } + return RemovePath(src); } static int RenameFile(const string &src, const string &dest, const int mode) { - if (mode == DIRMODE_FILE_THROW_ERR || mode == DIRMODE_DIRECTORY_THROW_ERR) { - auto [fileExist, ignore] = JudgeExistAndEmpty(dest); - if (fileExist) { + filesystem::path dstPath(dest); + if (mode == DIRMODE_FILE_THROW_ERR) { + if (filesystem::exists(dstPath)) { HILOGE("Failed to move file due to existing destPath with throw err"); return EEXIST; } } - uv_fs_t rename_req; - int res = uv_fs_rename(nullptr, &rename_req, src.c_str(), dest.c_str(), nullptr); - uv_fs_req_cleanup(&rename_req); - if (res < 0 && (string_view(uv_err_name(res)) == "EXDEV")) { + filesystem::path srcPath(src); + std::error_code errCode; + filesystem::rename(srcPath, dstPath, errCode); + if (errCode.value() == EXDEV) { HILOGE("Failed to rename file due to EXDEV"); return CopyAndDeleteFile(src, dest); } - if (res < 0) { - HILOGE("Failed to move file using rename syscall"); - return -res; - } - return ERRNO_NOERR; + return errCode.value(); } static int32_t FilterFunc(const struct dirent *filename) @@ -141,17 +133,27 @@ static int32_t FilterFunc(const struct dirent *filename) static int RenameDir(const string &src, const string &dest, const int mode, vector &errfiles) { - uv_fs_t rename_req; - int ret = uv_fs_rename(nullptr, &rename_req, src.c_str(), dest.c_str(), nullptr); - uv_fs_req_cleanup(&rename_req); - if (ret < 0 && (string_view(uv_err_name(ret)) == "EXDEV")) { - HILOGE("Failed to rename file due to EXDEV"); + 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"); + 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(); + } + } + if (errCode.value() != 0) { + HILOGE("Failed to rename file, error code: %{public}d", errCode.value()); + return errCode.value(); + } + } else { return RecurMoveDir(src, dest, mode, errfiles); } - if (ret < 0) { - HILOGE("Failed to move file using rename syscall"); - return -ret; - } return ERRNO_NOERR; } @@ -169,17 +171,6 @@ static void Deleter(struct NameListArg *arg) free(arg->namelist); } -static int MoveSubDir(const string &srcPath, const string &destPath, const int mode, - vector &errfiles) -{ - auto [fileExist, ignore] = JudgeExistAndEmpty(destPath); - if (fileExist) { - return RecurMoveDir(srcPath, destPath, mode, errfiles); - } else { - return RenameDir(srcPath, destPath, mode, errfiles); - } -} - static int RecurMoveDir(const string &srcPath, const string &destPath, const int mode, vector &errfiles) { @@ -195,11 +186,18 @@ static int RecurMoveDir(const string &srcPath, const string &destPath, const int if ((ptr->namelist[i])->d_type == DT_DIR) { string srcTemp = srcPath + '/' + string((ptr->namelist[i])->d_name); string destTemp = destPath + '/' + string((ptr->namelist[i])->d_name); - int res = MoveSubDir(srcTemp, destTemp, mode, errfiles); - if (res == ERRNO_NOERR) { + size_t size = errfiles.size(); + int res = RenameDir(srcTemp, destTemp, mode, errfiles); + if (res != ERRNO_NOERR) { + return res; + } + if (size != errfiles.size()) { continue; } - return res; + res = RemovePath(srcTemp); + if (res) { + return res; + } } else { string src = srcPath + '/' + string((ptr->namelist[i])->d_name); string dest = destPath + '/' + string((ptr->namelist[i])->d_name); @@ -207,10 +205,9 @@ static int RecurMoveDir(const string &srcPath, const string &destPath, const int if (res == EEXIST && mode == DIRMODE_FILE_THROW_ERR) { errfiles.emplace_back(src, dest); continue; - } else if (res == ERRNO_NOERR) { - continue; - } else { - HILOGE("Failed to rename file"); + } + if (res != ERRNO_NOERR) { + HILOGE("Failed to rename file for error %{public}d", res); return res; } } @@ -226,32 +223,32 @@ static int MoveDirFunc(const string &src, const string &dest, const int mode, ve } string dirName = string(src).substr(found); string destStr = dest + dirName; - auto [destStrExist, destStrEmpty] = JudgeExistAndEmpty(destStr); - if (destStrExist && !destStrEmpty) { + filesystem::path dstPath(destStr); + if (filesystem::exists(dstPath)) { if (mode == DIRMODE_DIRECTORY_REPLACE) { - if (!RmDirectory(destStr)) { - return ENOTEMPTY; + int removeRes = RmDirectory(destStr); + if (removeRes) { + HILOGE("Failed to remove dest directory in DIRMODE_DIRECTORY_REPLACE"); + return removeRes; } - return RenameDir(src, destStr, mode, errfiles); } if (mode == DIRMODE_DIRECTORY_THROW_ERR) { return ENOTEMPTY; } - int res = RecurMoveDir(src, destStr, mode, errfiles); - if (res == ERRNO_NOERR && mode == DIRMODE_FILE_REPLACE) { - if (!RmDirectory(src)) { - HILOGE("Failed to rm src dir with DIRMODE_FILE_REPLACE"); - return ENOTEMPTY; - } - } else if (mode == DIRMODE_FILE_THROW_ERR) { + } + int res = RenameDir(src, destStr, mode, errfiles); + if (res == ERRNO_NOERR) { + if (mode == DIRMODE_FILE_THROW_ERR && errfiles.size() != 0) { HILOGE("Failed to movedir with some conflicted files"); return EEXIST; } - return res; - } else { - return RenameDir(src, destStr, mode, errfiles); + int removeRes = RmDirectory(src); + if (removeRes) { + HILOGE("Failed to remove src directory"); + return removeRes; + } } - return ERRNO_NOERR; + return res; } static napi_value GetErrData(napi_env env, vector &errfiles) diff --git a/interfaces/kits/js/src/mod_fs/properties/movedir.h b/interfaces/kits/js/src/mod_fs/properties/movedir.h index 30275ef23..d1a116d23 100755 --- a/interfaces/kits/js/src/mod_fs/properties/movedir.h +++ b/interfaces/kits/js/src/mod_fs/properties/movedir.h @@ -29,6 +29,7 @@ constexpr int DIRMODE_MAX = 3; constexpr int FILE_DISMATCH = 0; constexpr int FILE_MATCH = 1; +constexpr int MOVEDIR_DEFAULT_PERM = 0770; enum ModeOfMoveDir { DIRMODE_DIRECTORY_THROW_ERR = 0, -- Gitee