diff --git a/interfaces/kits/js/BUILD.gn b/interfaces/kits/js/BUILD.gn index 0a5a0faecf4092ac11a40e88332bc6aab5b36b1d..2925faf87925f38a57bb753c32708d8312f7fcf7 100644 --- a/interfaces/kits/js/BUILD.gn +++ b/interfaces/kits/js/BUILD.gn @@ -155,6 +155,7 @@ ohos_shared_library("fs") { "src/mod_fs/properties/copy_file.cpp", "src/mod_fs/properties/copydir.cpp", "src/mod_fs/properties/create_stream.cpp", + "src/mod_fs/properties/dup.cpp", "src/mod_fs/properties/fdopen_stream.cpp", "src/mod_fs/properties/listfile.cpp", "src/mod_fs/properties/move.cpp", diff --git a/interfaces/kits/js/src/mod_fs/common_func.cpp b/interfaces/kits/js/src/mod_fs/common_func.cpp index 35119fd510dec0b99e7c634b20633b8c0da1e5ce..827e13d87e35095ad58200d6d48db3d28820bb20 100644 --- a/interfaces/kits/js/src/mod_fs/common_func.cpp +++ b/interfaces/kits/js/src/mod_fs/common_func.cpp @@ -21,6 +21,8 @@ #include #include +#include "class_file/file_entity.h" +#include "class_file/file_n_exporter.h" #include "class_stat/stat_entity.h" #include "class_stat/stat_n_exporter.h" #ifndef WIN_PLATFORM @@ -29,6 +31,7 @@ #endif #include "filemgmt_libhilog.h" #include "filemgmt_libn.h" +#include "file_utils.h" namespace OHOS { namespace FileManagement { @@ -108,6 +111,47 @@ unsigned int CommonFunc::ConvertJsFlags(unsigned int &flags) return flagsABI; } +NVal CommonFunc::InstantiateFile(napi_env env, int fd, string pathOrUri, bool isUri) +{ + napi_value objFile = NClass::InstantiateClass(env, FileNExporter::className_, {}); + if (!objFile) { + HILOGE("Failed to instantiate class"); + NError(EIO).ThrowErr(env); + int ret = close(fd); + if (ret < 0) { + HILOGE("Failed to close fd"); + } + return NVal(); + } + + auto fileEntity = NClass::GetEntityOf(env, objFile); + if (!fileEntity) { + HILOGE("Failed to get fileEntity"); + NError(EIO).ThrowErr(env); + int ret = close(fd); + if (ret < 0) { + HILOGE("Failed to close fd"); + } + return NVal(); + } + auto fdg = CreateUniquePtr(fd, false); + if (fdg == nullptr) { + HILOGE("Failed to request heap memory."); + NError(ENOMEM).ThrowErr(env); + return NVal(); + } + fileEntity->fd_.swap(fdg); + HILOGI("path = %{public}s", pathOrUri.c_str()); + if (isUri) { + fileEntity->path_ = ""; + fileEntity->uri_ = pathOrUri; + } else { + fileEntity->path_ = pathOrUri; + fileEntity->uri_ = ""; + } + return { env, objFile }; +} + NVal CommonFunc::InstantiateStat(napi_env env, const uv_stat_t &buf) { napi_value objStat = NClass::InstantiateClass(env, StatNExporter::className_, {}); diff --git a/interfaces/kits/js/src/mod_fs/common_func.h b/interfaces/kits/js/src/mod_fs/common_func.h index 46821e21d21e31206e912b2d024fb9eb329f0ccf..cd1b3e30b7136815ccc62042a1a61cd5f5ae837b 100644 --- a/interfaces/kits/js/src/mod_fs/common_func.h +++ b/interfaces/kits/js/src/mod_fs/common_func.h @@ -56,6 +56,7 @@ void InitOpenMode(napi_env env, napi_value exports); struct CommonFunc { static unsigned int ConvertJsFlags(unsigned int &flags); + static LibN::NVal InstantiateFile(napi_env env, int fd, std::string pathOrUri, bool isUri); static LibN::NVal InstantiateStat(napi_env env, const uv_stat_t &buf); #ifndef WIN_PLATFORM static LibN::NVal InstantiateStream(napi_env env, std::unique_ptr fp); diff --git a/interfaces/kits/js/src/mod_fs/properties/dup.cpp b/interfaces/kits/js/src/mod_fs/properties/dup.cpp new file mode 100644 index 0000000000000000000000000000000000000000..c3ed06945c6f333aa3a8338dacaad8b3e2b4a9a3 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/dup.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2023 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "dup.h" + +#include +#include +#include +#include + +#include "class_file/file_entity.h" +#include "common_func.h" +#include "filemgmt_libhilog.h" + +namespace OHOS::FileManagement::ModuleFileIO { +using namespace std; +using namespace OHOS::FileManagement::LibN; + +napi_value Dup::Sync(napi_env env, napi_callback_info info) +{ + NFuncArg funcArg(env, info); + if (!funcArg.InitArgs(NARG_CNT::ONE)) { + HILOGE("Number of arguments unmatched"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + auto [succ, srcFd] = NVal(env, funcArg[NARG_POS::FIRST]).ToInt32(); + if (!succ || srcFd < 0) { + HILOGE("Invalid fd"); + NError(EINVAL).ThrowErr(env); + return nullptr; + } + int dstFd = dup(srcFd); + HILOGI("dstFd = %{public}d", dstFd); + if (dstFd < 0) { + HILOGE("Failed to dup fd, errno: %{public}d", errno); + NError(errno).ThrowErr(env); + return nullptr; + } + std::unique_ptr readlink_req = { + new (std::nothrow) uv_fs_t, CommonFunc::fs_req_cleanup }; + if (!readlink_req) { + HILOGE("Failed to request heap memory."); + NError(ENOMEM).ThrowErr(env); + return nullptr; + } + auto pid = getpid(); + string path = "/proc/" + to_string(pid) + "/fd/" + to_string(dstFd); + int ret = uv_fs_readlink(nullptr, readlink_req.get(), path.c_str(), nullptr); + if (ret < 0) { + HILOGE("Failed to readlink fd, ret: %{public}d", ret); + NError(ret).ThrowErr(env); + return nullptr; + } + return CommonFunc::InstantiateFile(env, dstFd, string(static_cast(readlink_req->ptr), + ret), false).val_; +} +} // namespace OHOS::FileManagement::ModuleFileIO \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/dup.h b/interfaces/kits/js/src/mod_fs/properties/dup.h new file mode 100644 index 0000000000000000000000000000000000000000..08748098c34d5bb4ac6dd77c379a435612e36578 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/dup.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2023 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_DUP_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_DUP_H + +#include "filemgmt_libn.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +class Dup final { +public: + static napi_value Sync(napi_env env, napi_callback_info info); +}; + +struct AsyncDupArg { + int dstFd = 0; + std::string path; +}; + +const std::string PROCEDURE_FD2FILE_NAME = "FileIODup"; +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_DUP_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/prop_n_exporter.cpp b/interfaces/kits/js/src/mod_fs/properties/prop_n_exporter.cpp index 6b705dc8439ae37ca7e98e80266d9aa3a9ab95be..6b54ad9344c7759d3896c6632d5e2d9a767043d4 100644 --- a/interfaces/kits/js/src/mod_fs/properties/prop_n_exporter.cpp +++ b/interfaces/kits/js/src/mod_fs/properties/prop_n_exporter.cpp @@ -44,6 +44,7 @@ #include "copy_file.h" #include "copydir.h" #include "create_stream.h" +#include "dup.h" #include "fdopen_stream.h" #include "listfile.h" #include "move.h" @@ -594,6 +595,7 @@ bool PropNExporter::Export() NVal::DeclareNapiFunction("copyFileSync", CopyFile::Sync), NVal::DeclareNapiFunction("createStream", CreateStream::Async), NVal::DeclareNapiFunction("createStreamSync", CreateStream::Sync), + NVal::DeclareNapiFunction("dup", Dup::Sync), NVal::DeclareNapiFunction("fdopenStream", FdopenStream::Async), NVal::DeclareNapiFunction("fdopenStreamSync", FdopenStream::Sync), NVal::DeclareNapiFunction("listFile", ListFile::Async),