diff --git a/interfaces/kits/js/src/mod_fs/properties/movedir.cpp b/interfaces/kits/js/src/mod_fs/properties/movedir.cpp index 57ffb70fe1e8c3d252a435e7bbcefc058e4e0931..285c2fe01f63d4ff32117a70d4d89fb79eaa0a78 100644 --- a/interfaces/kits/js/src/mod_fs/properties/movedir.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/movedir.cpp @@ -128,10 +128,35 @@ static int RestoreTime(const string &srcPath, const string &destPath) return ERRNO_NOERR; } +static int UpdateTime(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; + } + + auto currentTime = chrono::system_clock::now(); + auto seconds = chrono::time_point_cast(currentTime); + auto nanoseconds = chrono::time_point_cast(currentTime) - + chrono::time_point_cast(seconds); + double atime = seconds.time_since_epoch().count() + nanoseconds.count() / 1e9; + double mtime = atime; + + int ret = uv_fs_utime(nullptr, utime_req.get(), path.c_str(), atime, mtime, nullptr); + if (ret < 0) { + HILOGE("Failed to update time for %s, error code: %d", path.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)) { + bool destExists = filesystem::exists(dstPath); + if (destExists) { int removeRes = RemovePath(dest); if (removeRes != 0) { HILOGE("Failed to remove dest file"); @@ -144,10 +169,18 @@ 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 (!destExists) { + int ret = RestoreTime(srcPath, dstPath); + if (ret) { + HILOGE("Failed to utime dstPath"); + return ret; + } + } else { + int UpdateTimeRet = UpdateTime(dstPath); + if (UpdateTimeRet) { + HILOGE("Failed to update time for dest directory"); + return UpdateTimeRet; + } } return RemovePath(src); } @@ -198,11 +231,6 @@ 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"); - return ret; - } return RecurMoveDir(src, dest, mode, errfiles); } if (errCode.value() != 0) { @@ -229,8 +257,7 @@ static void Deleter(struct NameListArg *arg) static int RecurMoveDir(const string &srcPath, const string &destPath, const int mode, deque &errfiles) { - filesystem::path dpath(destPath); - if (!filesystem::is_directory(dpath)) { + if (!filesystem::is_directory(filesystem::path(destPath))) { errfiles.emplace_front(srcPath, destPath); return ERRNO_NOERR; } @@ -240,35 +267,34 @@ static int RecurMoveDir(const string &srcPath, const string &destPath, const int HILOGE("Failed to request heap memory."); return ENOMEM; } - int num = scandir(srcPath.c_str(), &(ptr->namelist), FilterFunc, alphasort); - ptr->num = num; - for (int i = 0; i < num; i++) { - 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); - size_t size = errfiles.size(); - int res = RenameDir(srcTemp, destTemp, mode, errfiles); + ptr->num = scandir(srcPath.c_str(), &(ptr->namelist), FilterFunc, alphasort); + bool isCrossDevice = false; + for (int i = 0; i < ptr->num; i++) { + string srcTemp = srcPath + '/' + string((ptr->namelist[i])->d_name); + string destTemp = destPath + '/' + string((ptr->namelist[i])->d_name); + int res = ((ptr->namelist[i])->d_type == DT_DIR) ? + RenameDir(srcTemp, destTemp, mode, errfiles) : + RenameFile(srcTemp, destTemp, mode, errfiles); if (res != ERRNO_NOERR) { + HILOGE("Failed to rename for error %{public}d", res); return res; } - if (size != errfiles.size()) { - continue; - } - res = RemovePath(srcTemp); - if (res) { + if (errfiles.size() == 0 && RemovePath(srcTemp)) { return res; } - } else { - string src = srcPath + '/' + string((ptr->namelist[i])->d_name); - string dest = destPath + '/' + string((ptr->namelist[i])->d_name); - int res = RenameFile(src, dest, mode, errfiles); - if (res != ERRNO_NOERR) { - HILOGE("Failed to rename file for error %{public}d", res); - return res; + if (res == EXDEV) { + isCrossDevice = true; + } + if (isCrossDevice) { + int UpdateTimeRet = filesystem::exists(destPath) ? UpdateTime(destPath) : RestoreTime(srcPath, destPath); + if (UpdateTimeRet) { + HILOGE("Failed to modify time for dest directory"); + return UpdateTimeRet; } } } + return ERRNO_NOERR; }