diff --git a/interfaces/kits/js/src/mod_fs/properties/copy.cpp b/interfaces/kits/js/src/mod_fs/properties/copy.cpp index 2b8ee39636be3271959fb8067ee9c1f106c09df9..d3bbdee8766964337f1514834f711f6888fe350a 100644 --- a/interfaces/kits/js/src/mod_fs/properties/copy.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/copy.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 Huawei Device Co., Ltd. + * Copyright (c) 2023-2024 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -18,8 +18,6 @@ #include #include #include -#include -#include #include #include #include @@ -50,6 +48,7 @@ const string PROCEDURE_COPY_NAME = "FileFSCopy"; constexpr int DISMATCH = 0; constexpr int MATCH = 1; constexpr int BUF_SIZE = 1024; +constexpr size_t MAX_SIZE = 0x7ffff000; constexpr std::chrono::milliseconds NOTIFY_PROGRESS_DELAY(200); std::recursive_mutex Copy::mutex_; std::map> Copy::jsCbMap_; @@ -131,21 +130,57 @@ void Copy::CheckOrCreatePath(const std::string &destPath) { if (!filesystem::exists(destPath)) { HILOGI("destPath not exist, destPath = %{public}s", destPath.c_str()); - ofstream out; - out.open(destPath.c_str()); - out.close(); + auto file = open(destPath.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); + if (file < 0) { + HILOGE("Error opening file descriptor. errno = %{public}d", errno); + } + close(file); } } int Copy::CopyFile(const string &src, const string &dest) { HILOGD("src = %{public}s, dest = %{public}s", src.c_str(), dest.c_str()); - filesystem::path dstPath(dest); - 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(); + auto srcFd = open(src.c_str(), O_RDONLY); + auto destFd = open(dest.c_str(), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); + if (srcFd < 0 || destFd < 0) { + HILOGE("Error opening file descriptor. errno = %{public}d", errno); + close(srcFd); + close(destFd); + return errno; + } + auto srcFdg = CreateUniquePtr(srcFd, true); + auto destFdg = CreateUniquePtr(destFd, true); + std::unique_ptr sendFileReq = { + new (nothrow) uv_fs_t, CommonFunc::fs_req_cleanup }; + if (sendFileReq == nullptr) { + HILOGE("Failed to request heap memory."); + return ENOMEM; + } + int64_t offset = 0; + struct stat srcStat{}; + if (fstat(srcFdg->GetFD(), &srcStat) < 0) { + HILOGE("Failed to get stat of file by fd: %{public}d ,errno = %{public}d", srcFdg->GetFD(), errno); + return errno; + } + int64_t size = static_cast(srcStat.st_size); + int ret = 0; + while (size > 0) { + ret = uv_fs_sendfile(nullptr, sendFileReq.get(), destFdg->GetFD(), srcFdg->GetFD(), + offset, MAX_SIZE, nullptr); + if (ret < 0) { + HILOGE("Failed to sendfile by errno : %{public}d", errno); + return errno; + } + offset += static_cast(ret); + size -= static_cast(ret); + if (ret == 0) { + break; + } + } + if (size != 0) { + HILOGE("The execution of the sendfile task was terminated, remaining file size %{public}ld", size); + return E_IO; } return ERRNO_NOERR; } @@ -617,7 +652,7 @@ void Copy::GetNotifyEvent(std::shared_ptr infos) std::string Copy::ConvertUriToPath(const std::string &uri) { FileUri fileUri(uri); - return fileUri.GetPath(); + return fileUri.GetRealPath(); } tuple> Copy::CreateFileInfos(