diff --git a/interfaces/kits/cj/BUILD.gn b/interfaces/kits/cj/BUILD.gn index 3c36daad0e48172790776e48b8cd8cc0f45f5d9b..1a9cc0b52003c63b20c4147d6ec8b1bc4d2a30e2 100644 --- a/interfaces/kits/cj/BUILD.gn +++ b/interfaces/kits/cj/BUILD.gn @@ -15,50 +15,6 @@ import("//build/ohos.gni") import("//foundation/filemanagement/file_api/file_api.gni") ohos_shared_library("cj_file_fs_ffi") { - sanitize = { - integer_overflow = true - ubsan = true - boundary_sanitize = true - cfi = true - cfi_cross_dso = true - debug = false - } - - defines = [] - cflags = [ - "-fvisibility=hidden", - "-fdata-sections", - "-ffunction-sections", - "-Oz", - ] - cflags_cc = [ - "-fvisibility-inlines-hidden", - "-Oz", - ] - if (is_mingw || is_mac || is_linux) { - defines += [ "PREVIEW" ] - } - - if (current_os == "ohos" && current_cpu == "x86_64") { - defines += [ "SIMULATOR" ] - } - if (is_ohos) { - defines += [ "OHOS_PLATFORM" ] - if (use_musl && !is_asan) { - defines += [ "HOOK_ENABLE" ] - } - } else if (is_mingw) { - defines += [ "WINDOWS_PLATFORM" ] - cflags_cc += [ "-std=c++17" ] - } else if (is_mac) { - defines += [ "MAC_PLATFORM" ] - } else if (is_linux) { - defines += [ "LINUX_PLATFORM" ] - cflags_cc += [ "-std=c++17" ] - } else if (is_arkui_x && target_os == "ios") { - defines += [ "IOS_PLATFORM" ] - } - include_dirs = [ "${src_path}/common", "${src_path}/common/file_helper", @@ -78,84 +34,101 @@ ohos_shared_library("cj_file_fs_ffi") { "${file_api_path}/interfaces/kits/rust/include", ] - if (!defined(defines)) { - defines = [] - } + sources = [ + "../js/src/common/file_helper/fd_guard.cpp", + "../js/src/mod_fs/class_file/file_n_exporter.cpp", + "../js/src/mod_fs/class_stream/stream_n_exporter.cpp", + "../js/src/mod_fs/common_func.cpp", + "src/copy.cpp", + "src/copy_dir.cpp", + "src/copy_file.cpp", + "src/fdatasync.cpp", + "src/file_ffi.cpp", + "src/file_fs_ffi.cpp", + "src/file_fs_impl.cpp", + "src/file_impl.cpp", + "src/fsync.cpp", + "src/list_file.cpp", + "src/lseek.cpp", + "src/mkdtemp.cpp", + "src/move_file.cpp", + "src/randomAccessFile_impl.cpp", + "src/readerIterator_impl.cpp", + "src/stat_ffi.cpp", + "src/stat_impl.cpp", + "src/stream_ffi.cpp", + "src/stream_impl.cpp", + "src/symlink.cpp", + "src/task_signal_impl.cpp", + "src/translistener.cpp", + "src/uni_error.cpp", + "src/utils.cpp", + "src/watcher_impl.cpp", + "src/xattr.cpp", + "src/xattr_ffi.cpp", + ] + deps = [ + "${file_api_path}/interfaces/kits/js:build_kits_js", + "${file_api_path}/interfaces/kits/js:fs", + "${file_api_path}/interfaces/kits/native:remote_uri_native", + "${file_api_path}/interfaces/kits/native:task_signal_native", + "${file_api_path}/interfaces/kits/rust:rust_file", + "${utils_path}/filemgmt_libhilog:filemgmt_libhilog", + "${utils_path}/filemgmt_libn:filemgmt_libn", + ] + + cflags_cc = [ "-std=c++17" ] use_exceptions = true + if (use_mingw_win) { + defines = [ "WIN_PLATFORM" ] + } + if (use_mac) { + defines = [ "IOS_PLATFORM" ] + } + + external_deps = [ + "ability_base:zuri", + "ability_runtime:ability_manager", + "ability_runtime:abilitykit_native", + "access_token:libtokenid_sdk", + "app_file_service:fileuri_native", + "bounds_checking_function:libsec_shared", + "bundle_framework:appexecfwk_base", + "bundle_framework:appexecfwk_core", + "c_utils:utils", + "data_share:datashare_common", + "data_share:datashare_consumer", + "dfs_service:distributed_file_daemon_kit_inner", + "hilog:libhilog", + "ipc:ipc_core", + "napi:ace_napi", + "napi:cj_bind_ffi", + "napi:cj_bind_native", + "samgr:samgr_proxy", + ] - if (product_name != "ohos-sdk") { - deps = [ - "${file_api_path}/interfaces/kits/js:build_kits_js", - "${file_api_path}/interfaces/kits/js:fs", - "${file_api_path}/interfaces/kits/native:remote_uri_native", - "${file_api_path}/interfaces/kits/native:task_signal_native", - "${file_api_path}/interfaces/kits/rust:rust_file", - "${utils_path}/filemgmt_libhilog:filemgmt_libhilog", - "${utils_path}/filemgmt_libn:filemgmt_libn", + if (!use_mingw_win && !use_mac) { + cflags = [ + "-fvisibility=hidden", + "-fdata-sections", + "-ffunction-sections", + "-Oz", ] - external_deps = [ - "ability_base:zuri", - "ability_runtime:ability_manager", - "ability_runtime:abilitykit_native", - "access_token:libtokenid_sdk", - "app_file_service:fileuri_native", - "bounds_checking_function:libsec_shared", - "bundle_framework:appexecfwk_base", - "bundle_framework:appexecfwk_core", - "c_utils:utils", - "data_share:datashare_common", - "data_share:datashare_consumer", - "dfs_service:distributed_file_daemon_kit_inner", - "hilog:libhilog", - "ipc:ipc_core", - "napi:ace_napi", - "napi:cj_bind_ffi", - "napi:cj_bind_native", - "samgr:samgr_proxy", + cflags_cc += [ + "-fvisibility-inlines-hidden", + "-Oz", ] - sources = [ - "../js/src/common/file_helper/fd_guard.cpp", - "../js/src/mod_fs/class_file/file_n_exporter.cpp", - "../js/src/mod_fs/class_stream/stream_n_exporter.cpp", - "../js/src/mod_fs/common_func.cpp", - "src/copy.cpp", - "src/copy_dir.cpp", - "src/copy_file.cpp", - "src/fdatasync.cpp", - "src/file_ffi.cpp", - "src/file_fs_ffi.cpp", - "src/file_fs_impl.cpp", - "src/file_impl.cpp", - "src/fsync.cpp", - "src/list_file.cpp", - "src/lseek.cpp", - "src/mkdtemp.cpp", - "src/move_file.cpp", - "src/randomAccessFile_impl.cpp", - "src/readerIterator_impl.cpp", - "src/stat_ffi.cpp", - "src/stream_ffi.cpp", - "src/stream_impl.cpp", - "src/symlink.cpp", - "src/task_signal_impl.cpp", - "src/translistener.cpp", - "src/uni_error.cpp", - "src/utils.cpp", - "src/watcher_impl.cpp", - ] - } else { - defines += [ "PREVIEWER" ] - sources = [ "src/file_fs_mock.cpp" ] - external_deps = [ "napi:cj_bind_ffi" ] - } - - if (current_os == "ohos") { - defines += [ "OHOS_PLATFORM" ] - } - - if (current_os == "mingw") { - defines += [ "WINDOWS_PLATFORM" ] + defines = [ "FILE_API_TRACE" ] + branch_protector_ret = "pac_ret" + sanitize = { + integer_overflow = true + ubsan = true + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false + } } innerapi_tags = [ "platformsdk" ] @@ -164,16 +137,6 @@ ohos_shared_library("cj_file_fs_ffi") { } ohos_shared_library("cj_statvfs_ffi") { - sanitize = { - integer_overflow = true - ubsan = true - boundary_sanitize = true - cfi = true - cfi_cross_dso = true - debug = false - } - - defines = [] cflags = [ "-fvisibility=hidden", "-fdata-sections", @@ -184,102 +147,34 @@ ohos_shared_library("cj_statvfs_ffi") { "-fvisibility-inlines-hidden", "-Oz", ] - if (is_mingw || is_mac || is_linux) { - defines += [ "PREVIEW" ] + branch_protector_ret = "pac_ret" + sanitize = { + integer_overflow = true + ubsan = true + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false } - if (current_os == "ohos" && current_cpu == "x86_64") { - defines += [ "SIMULATOR" ] - } - if (is_ohos) { - defines += [ "OHOS_PLATFORM" ] - if (use_musl && !is_asan) { - defines += [ "HOOK_ENABLE" ] - } - } else if (is_mingw) { - defines += [ "WINDOWS_PLATFORM" ] - cflags_cc += [ "-std=c++17" ] - } else if (is_mac) { - defines += [ "MAC_PLATFORM" ] - } else if (is_linux) { - defines += [ "LINUX_PLATFORM" ] - cflags_cc += [ "-std=c++17" ] - } else if (is_arkui_x && target_os == "ios") { - defines += [ "IOS_PLATFORM" ] - } + include_dirs = [ "${file_api_path}/interfaces/kits/cj/src" ] - include_dirs = [ - "${src_path}/common", - "${src_path}/common/napi", - "${src_path}/common/napi/n_async", - "${src_path}/common/file_helper", - "${src_path}/mod_fs", - "${src_path}/mod_fs/class_randomaccessfile", - "${src_path}/mod_fs/class_readeriterator", - "${src_path}/mod_fs/properties", - "${utils_path}/common/include", - "${utils_path}/filemgmt_libhilog", - "${utils_path}/filemgmt_libh", - "${utils_path}/filemgmt_libn/include", - "${file_api_path}/interfaces/kits/cj/src", - "${file_api_path}/interfaces/kits/native/remote_uri", - "${file_api_path}/interfaces/kits/native/task_signal", - "${file_api_path}/interfaces/kits/rust/include", + sources = [ + "src/statvfs_ffi.cpp", + "src/statvfs_impl.cpp", + "src/uni_error.cpp", ] - if (!defined(defines)) { - defines = [] - } - - use_exceptions = true - - if (product_name != "ohos-sdk") { - deps = [ - "${file_api_path}/interfaces/kits/js:build_kits_js", - "${file_api_path}/interfaces/kits/js:fs", - "${file_api_path}/interfaces/kits/native:remote_uri_native", - "${file_api_path}/interfaces/kits/native:task_signal_native", - "${file_api_path}/interfaces/kits/rust:rust_file", - "${utils_path}/filemgmt_libhilog:filemgmt_libhilog", - "${utils_path}/filemgmt_libn:filemgmt_libn", - ] - external_deps = [ - "ability_base:zuri", - "ability_runtime:ability_manager", - "ability_runtime:abilitykit_native", - "access_token:libtokenid_sdk", - "app_file_service:fileuri_native", - "bounds_checking_function:libsec_shared", - "bundle_framework:appexecfwk_base", - "bundle_framework:appexecfwk_core", - "c_utils:utils", - "data_share:datashare_common", - "data_share:datashare_consumer", - "dfs_service:distributed_file_daemon_kit_inner", - "hilog:libhilog", - "ipc:ipc_core", - "napi:ace_napi", - "napi:cj_bind_ffi", - "napi:cj_bind_native", - "samgr:samgr_proxy", - ] - sources = [ - "src/statvfs_ffi.cpp", - "src/statvfs_impl.cpp", - "src/uni_error.cpp", - ] - } else { - defines += [ "PREVIEWER" ] - external_deps = [ "napi:cj_bind_ffi" ] - } - - if (current_os == "ohos") { - defines += [ "OHOS_PLATFORM" ] - } - - if (current_os == "mingw") { - defines += [ "WINDOWS_PLATFORM" ] - } + deps = [ + "${utils_path}/filemgmt_libhilog:filemgmt_libhilog", + "${utils_path}/filemgmt_libn:filemgmt_libn", + ] + external_deps = [ + "hilog:libhilog", + "napi:ace_napi", + "napi:cj_bind_ffi", + "napi:cj_bind_native", + ] innerapi_tags = [ "platformsdk" ] part_name = "file_api" diff --git a/interfaces/kits/cj/src/file_fs_ffi.cpp b/interfaces/kits/cj/src/file_fs_ffi.cpp index 0c0fa60a2904841aad37ab10e5a3c4f9336ec922..d0ee85ee47488bfb88b0bb0bc668472ed4025b21 100644 --- a/interfaces/kits/cj/src/file_fs_ffi.cpp +++ b/interfaces/kits/cj/src/file_fs_ffi.cpp @@ -650,6 +650,22 @@ RetDataBool FfiOHOSFileFsAccess(const char* path) return ret; } +RetDataBool FfiOHOSFileFsAccessExt(const char* path, int32_t mode, int32_t flag) +{ + LOGI("FS_TEST::FfiOHOSFileFsAccessExt"); + RetDataBool ret = { .code = ERR_INVALID_INSTANCE_CODE, .data = 0 }; + auto [status, accessStatus] = FileFsImpl::Access(path, mode, flag); + ret.code = status; + if (status != SUCCESS_CODE) { + LOGI("FS_TEST::FfiOHOSFileFsAccessExt error"); + ret.data = false; + return ret; + } + LOGI("FS_TEST::FfiOHOSFileFsAccessExt success"); + ret.data = accessStatus; + return ret; +} + int32_t FfiOHOSFileFsTruncateByString(const char* file, int64_t len) { LOGI("FS_TEST::FfiOHOSFileFsTruncateByString"); diff --git a/interfaces/kits/cj/src/file_fs_ffi.h b/interfaces/kits/cj/src/file_fs_ffi.h index 6c8bf94ebd91100fd54101d5719553e2062c5505..8e8015d0f7e1d5160be7cf46cf1e185e3479dec7 100644 --- a/interfaces/kits/cj/src/file_fs_ffi.h +++ b/interfaces/kits/cj/src/file_fs_ffi.h @@ -50,6 +50,7 @@ extern "C" { FFI_EXPORT int32_t FfiOHOSFileFsRename(const char* oldFile, const char* newFile); FFI_EXPORT int32_t FfiOHOSFileFsUnlink(const char* path); FFI_EXPORT RetDataBool FfiOHOSFileFsAccess(const char* path); + FFI_EXPORT RetDataBool FfiOHOSFileFsAccessExt(const char* path, int32_t mode, int32_t flag); FFI_EXPORT RetDataI64 FfiOHOSFileFsOpen(const char* path, uint64_t mode); FFI_EXPORT RetDataI64 FfiOHOSFileFsRead(int32_t fd, char* buffer, int64_t bufLen, size_t length, int64_t offset); FFI_EXPORT RetDataI64 FfiOHOSFileFsReadCur(int32_t fd, char* buffer, int64_t bufLen, size_t length); diff --git a/interfaces/kits/cj/src/file_fs_impl.cpp b/interfaces/kits/cj/src/file_fs_impl.cpp index 9b261e51ad30031c8bd9d2f44ac3dd4c9d40fc81..4444a882401f7d506aced35f6d7b9bdc7809c53a 100644 --- a/interfaces/kits/cj/src/file_fs_impl.cpp +++ b/interfaces/kits/cj/src/file_fs_impl.cpp @@ -15,6 +15,15 @@ #include "file_fs_impl.h" +#if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM) +#include + +#include "bundle_mgr_proxy.h" +#include "ipc_skeleton.h" +#include "iservice_registry.h" +#include "system_ability_definition.h" +#endif + using namespace OHOS; using namespace OHOS::FFI; using namespace OHOS::FileManagement; @@ -23,6 +32,18 @@ using namespace OHOS::CJSystemapi::FileFs; namespace { +#if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM) +const std::string CLOUDDISK_FILE_PREFIX = "/data/storage/el2/cloud"; +const std::string DISTRIBUTED_FILE_PREFIX = "/data/storage/el2/distributedfiles"; +const std::string PACKAGE_NAME_FLAG = ""; +const std::string USER_ID_FLAG = ""; +const std::string PHYSICAL_PATH_PREFIX = "/mnt/hmdfs//account/device_view/local/data/"; +const std::string CLOUD_FILE_LOCATION = "user.cloud.location"; +const char POSITION_LOCAL = '1'; +const char POSITION_BOTH = '3'; +const int BASE_USER_RANGE = 200000; +#endif + std::tuple ParseFile(int32_t file) { if (file < 0) { @@ -106,7 +127,7 @@ std::tuple ParseRandomFile(std::string file) return { true, FileInfo { true, move(filePath), move(fdg) }, ERRNO_NOERR }; } -std::tuple GetFsAccess(const FileInfo &fileInfo) +std::tuple UvAccess(const std::string &path, int mode) { std::unique_ptr stat_req = { new (std::nothrow) uv_fs_t, CommonFunc::FsReqCleanup }; @@ -115,7 +136,7 @@ std::tuple GetFsAccess(const FileInfo &fileInfo) return {ENOMEM, false}; } bool isAccess = false; - int ret = uv_fs_access(nullptr, stat_req.get(), fileInfo.path.get(), 0, nullptr); + int ret = uv_fs_access(nullptr, stat_req.get(), path.c_str(), mode, nullptr); if (ret < 0 && (std::string_view(uv_err_name(ret)) != "ENOENT")) { LOGE("Failed to access file by path"); return {ret, false}; @@ -125,6 +146,81 @@ std::tuple GetFsAccess(const FileInfo &fileInfo) } return {SUCCESS_CODE, isAccess}; } + +#if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM) +bool IsCloudOrDistributedFilePath(const std::string &path) +{ + return path.find(CLOUDDISK_FILE_PREFIX) == 0 || path.find(DISTRIBUTED_FILE_PREFIX) == 0; +} + +int GetCurrentUserId() +{ + int uid = IPCSkeleton::GetCallingUid(); + int userId = uid / BASE_USER_RANGE; + return userId; +} + +sptr GetBundleMgrProxy() +{ + sptr systemAbilityManager = + OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (!systemAbilityManager) { + LOGE("Fail to get system ability mgr"); + return nullptr; + } + sptr remoteObject = + systemAbilityManager->GetSystemAbility(OHOS::BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); + if (!remoteObject) { + LOGE("Fail to get bundle manager proxy"); + return nullptr; + } + return iface_cast(remoteObject); +} + +std::string GetSelfBundleName() +{ + sptr bundleMgrProxy = GetBundleMgrProxy(); + if (!bundleMgrProxy) { + LOGE("BundleMgrProxy is nullptr"); + return ""; + } + OHOS::AppExecFwk::BundleInfo bundleInfo; + auto ret = bundleMgrProxy->GetBundleInfoForSelf(0, bundleInfo); + if (ret != 0) { + LOGE("BundleName get fail"); + return ""; + } + return bundleInfo.name; +} + +std::tuple HandleLocalCheck(const std::string &path, int mode) +{ + // check if the file of /data/storage/el2/cloud is on the local + if (path.find(CLOUDDISK_FILE_PREFIX) == 0) { + char val[2] = {'\0'}; + if (getxattr(path.c_str(), CLOUD_FILE_LOCATION.c_str(), val, sizeof(val)) < 0) { + LOGE("Get cloud file location fail, err: %{public}d", errno); + return {GetErrorCode(errno), false}; + } + if (val[0] == POSITION_LOCAL || val[0] == POSITION_BOTH) { + return {SUCCESS_CODE, true}; + } + return {GetErrorCode(ENOENT), false}; + } + // check if the distributed file of /data/storage/el2/distributedfiles is on the local, + // convert into physical path(/mnt/hmdfs//account/device_view/local/data/) and check + if (path.find(DISTRIBUTED_FILE_PREFIX) == 0) { + int userId = GetCurrentUserId(); + std::string bundleName = GetSelfBundleName(); + std::string relativePath = path.substr(DISTRIBUTED_FILE_PREFIX.length()); + std::string physicalPath = PHYSICAL_PATH_PREFIX + relativePath; + physicalPath.replace(physicalPath.find(USER_ID_FLAG), USER_ID_FLAG.length(), std::to_string(userId)); + physicalPath.replace(physicalPath.find(PACKAGE_NAME_FLAG), PACKAGE_NAME_FLAG.length(), bundleName); + return UvAccess(physicalPath, mode); + } + return {GetErrorCode(ENOENT), false}; +} +#endif } namespace OHOS { @@ -147,6 +243,10 @@ std::tuple> FileFsImpl::Stat(int32_t file) if (!nativeStat) { return {GetErrorCode(ENOMEM), nullptr}; } +#if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM) + auto fileInfoPtr = std::make_shared(std::move(fileInfo)); + nativeStat->SetFileInfo(fileInfoPtr); +#endif return {SUCCESS_CODE, nativeStat}; } @@ -169,6 +269,10 @@ std::tuple> FileFsImpl::Stat(std::string file) if (!nativeStat) { return {GetErrorCode(ENOMEM), nullptr}; } +#if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM) + auto fileInfoPtr = std::make_shared(std::move(fileInfo)); + nativeStat->SetFileInfo(fileInfoPtr); +#endif return {SUCCESS_CODE, nativeStat}; } @@ -915,18 +1019,14 @@ RetDataI64 FileFsImpl::WriteCur(int32_t fd, void* buf, size_t length, std::strin return ret; } -std::tuple FileFsImpl::Access(std::string path) +std::tuple FileFsImpl::Access(std::string path, int32_t mode, int32_t flag) { - auto [fileState, fileInfo] = ParseFile(path); - - if (fileState != SUCCESS_CODE) { - return {GetErrorCode(ENOMEM), false}; - } - auto [accessState, access] = GetFsAccess(fileInfo); - if (accessState < 0) { - return {GetErrorCode(accessState), false}; +#if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM) + if (flag == LOCAL_FLAG && IsCloudOrDistributedFilePath(path)) { + return HandleLocalCheck(path, mode); } - return {SUCCESS_CODE, access}; +#endif + return UvAccess(path, mode); } int FileFsImpl::Truncate(std::string file, int64_t len) diff --git a/interfaces/kits/cj/src/file_fs_impl.h b/interfaces/kits/cj/src/file_fs_impl.h index e9ce164b29cf7570f45ff82858f8b9b873247cd2..52ac4a4d701abc38658ce58a3801042501df9ed5 100644 --- a/interfaces/kits/cj/src/file_fs_impl.h +++ b/interfaces/kits/cj/src/file_fs_impl.h @@ -61,6 +61,10 @@ struct FileStruct { FileFs::FileEntity *fileEntity; }; namespace FileFs { +enum AccessFlag : int32_t { + DEFAULT_FLAG = -1, + LOCAL_FLAG, +}; class FileFsImpl { public: static std::tuple> Stat(int32_t file); @@ -81,7 +85,7 @@ public: static RetDataI64 ReadCur(int32_t fd, char* buf, int64_t bufLen, size_t length); static RetDataI64 Write(int32_t fd, void* buf, size_t length, int64_t offset, std::string encode); static RetDataI64 WriteCur(int32_t fd, void* buf, size_t length, std::string encode); - static std::tuple Access(std::string path); + static std::tuple Access(std::string path, int32_t mode = 0, int32_t flag = DEFAULT_FLAG); static int Truncate(std::string file, int64_t len); static int Truncate(int32_t file, int64_t len); static int Close(int32_t file); diff --git a/interfaces/kits/cj/src/stat_ffi.cpp b/interfaces/kits/cj/src/stat_ffi.cpp index 93d82cdcc140ae735d78acacd5441abb0c24eda7..15f0b5fc442217064e1d0e85789811133feafa5b 100644 --- a/interfaces/kits/cj/src/stat_ffi.cpp +++ b/interfaces/kits/cj/src/stat_ffi.cpp @@ -179,4 +179,17 @@ bool FfiOHOSStatIsSymbolicLink(int64_t id) } return instance->IsSymbolicLink(); } + +#if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM) +RetDataI32 FfiOHOSStatGetLocation(int64_t id) +{ + LOGI("FS_TEST:: FfiOHOSStatGetLocation"); + auto instance = FFIData::GetData(id); + if (!instance) { + LOGE("StatImpl instance not exist %{public}" PRId64, id); + return { .code = ERR_INVALID_INSTANCE_CODE, .data = 0 }; + } + return instance->GetLocation(); +} +#endif } \ No newline at end of file diff --git a/interfaces/kits/cj/src/stat_ffi.h b/interfaces/kits/cj/src/stat_ffi.h index 7b99b6341d0b6b9dc192d0cd72c8b3fa8d8d270b..0c40540ee871147520089be142e8201659dc4e08 100644 --- a/interfaces/kits/cj/src/stat_ffi.h +++ b/interfaces/kits/cj/src/stat_ffi.h @@ -37,6 +37,9 @@ extern "C" { FFI_EXPORT bool FfiOHOSStatIsFile(int64_t id); FFI_EXPORT bool FfiOHOSStatIsSocket(int64_t id); FFI_EXPORT bool FfiOHOSStatIsSymbolicLink(int64_t id); +#if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM) + FFI_EXPORT RetDataI32 FfiOHOSStatGetLocation(int64_t id); +#endif } #endif // OHOS_FILE_FS_STAT_FFI_H \ No newline at end of file diff --git a/interfaces/kits/cj/src/stat_impl.cpp b/interfaces/kits/cj/src/stat_impl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a857126a727ca51e910a9494c72af47d54475d16 --- /dev/null +++ b/interfaces/kits/cj/src/stat_impl.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2025 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 "stat_impl.h" +#if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM) +#include +#endif +#include "macro.h" +#include "uni_error.h" + +namespace OHOS { +namespace CJSystemapi { +namespace FileFs { +using namespace std; + +#if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM) +RetDataI32 StatImpl::GetLocation() +{ + auto value = static_cast(malloc(MAX_ATTR_NAME)); + if (value == nullptr) { + return { .code = GetErrorCode(ENOMEM), .data = LOCAL }; + } + ssize_t size = 0; + if (fileInfo_->isPath) { + size = getxattr(fileInfo_->path.get(), CLOUD_LOCATION_ATTR.c_str(), value, MAX_ATTR_NAME); + } else { + size = fgetxattr(fileInfo_->fdg->GetFD(), CLOUD_LOCATION_ATTR.c_str(), value, MAX_ATTR_NAME); + } + Location defaultLocation = LOCAL; + if (size <= 0) { + if (errno != ENODATA && errno != EOPNOTSUPP) { + LOGE("Getxattr value failed, errno is %{public}d", errno); + } + return { .code = SUCCESS_CODE, .data = defaultLocation }; + } + std::string location = string(value, static_cast(size)); + if (!std::all_of(location.begin(), location.end(), ::isdigit)) { + LOGE("Getxattr location is not all digit!"); + return { .code = SUCCESS_CODE, .data = defaultLocation }; + } + defaultLocation = static_cast(atoi(location.c_str())); + return { .code = SUCCESS_CODE, .data = defaultLocation }; +} +#endif +} +} +} diff --git a/interfaces/kits/cj/src/stat_impl.h b/interfaces/kits/cj/src/stat_impl.h index 36e99508f370d3944183f74ab0803b2ada7024c2..3b61dccc535e0ff6b04bcade450d8df02accbf64 100644 --- a/interfaces/kits/cj/src/stat_impl.h +++ b/interfaces/kits/cj/src/stat_impl.h @@ -33,11 +33,28 @@ namespace FileFs { constexpr int S_PREMISSION = 00000777; +#if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM) +const size_t MAX_ATTR_NAME = 64; +const std::string CLOUD_LOCATION_ATTR = "user.cloud.location"; +enum Location { + LOCAL = 1 << 0, + CLOUD = 1 << 1 +}; +#endif + class StatImpl : public OHOS::FFI::FFIData { public: OHOS::FFI::RuntimeType* GetRuntimeType() override { return GetClassType(); } explicit StatImpl(uv_stat_t stat) : real_(std::move(stat)) {} +#if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM) + RetDataI32 GetLocation(); + + void SetFileInfo(std::shared_ptr info) + { + fileInfo_ = info; + } +#endif inline int64_t GetIno() const { @@ -122,6 +139,9 @@ public: private: uv_stat_t real_; +#if !defined(WIN_PLATFORM) && !defined(IOS_PLATFORM) + std::shared_ptr fileInfo_ = nullptr; +#endif friend class OHOS::FFI::RuntimeType; friend class OHOS::FFI::TypeBase; diff --git a/interfaces/kits/cj/src/xattr.cpp b/interfaces/kits/cj/src/xattr.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5d711db86cdfd497012ffd6f27501b2e77b09f9f --- /dev/null +++ b/interfaces/kits/cj/src/xattr.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2025 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 "xattr.h" +#include +#include +#include "macro.h" +#include "securec.h" + +using namespace std; + +namespace { +constexpr size_t MAX_XATTR_SIZE = 4096; + +char* CreateCString(string str) +{ + auto ret = static_cast(malloc(str.size() + 1)); + if (strcpy_s(ret, str.size() + 1, str.c_str()) != 0) { + free(ret); + return nullptr; + } + return ret; +} + +bool IsIllegalXattr(const char *key, const char *value) +{ + bool isIllegalKey = strnlen(key, MAX_XATTR_SIZE + 1) > MAX_XATTR_SIZE; + if (isIllegalKey) { + LOGE("key is too loog"); + } + bool isIllegalValue = strnlen(value, MAX_XATTR_SIZE + 1) > MAX_XATTR_SIZE; + if (isIllegalValue) { + LOGE("value is too loog"); + } + return isIllegalKey || isIllegalValue; +} +} + +namespace OHOS { +namespace CJSystemapi { +namespace FileFs { + +int32_t Xattr::SetSync(const char *path, const char *key, const char *value) +{ + if (IsIllegalXattr(key, value)) { + return EINVAL; + } + if (setxattr(path, key, value, strnlen(value, MAX_XATTR_SIZE), 0) < 0) { + LOGE("setxattr fail, errno is %{public}d", errno); + return errno; + } + return SUCCESS_CODE; +} + +tuple Xattr::GetSync(const char *path, const char *key) +{ + ssize_t xAttrSize = getxattr(path, key, nullptr, 0); + if (xAttrSize == -1 || xAttrSize == 0) { + auto result = CreateCString(""); + if (result == nullptr) { + return { ENOMEM, nullptr }; + } + return { SUCCESS_CODE, result }; + } + auto xAttrValue = static_cast(malloc(static_cast(xAttrSize) + 1)); + if (xAttrValue == nullptr) { + return { ENOMEM, nullptr }; + } + xAttrSize = getxattr(path, key, xAttrValue, static_cast(xAttrSize)); + if (xAttrSize == -1) { + return { errno, nullptr }; + } + xAttrValue[xAttrSize] = '\0'; + return { SUCCESS_CODE, xAttrValue }; +} + +} // namespace FileFs +} // namespace CJSystemapi +} // namespace OHOS diff --git a/interfaces/kits/cj/src/xattr.h b/interfaces/kits/cj/src/xattr.h new file mode 100644 index 0000000000000000000000000000000000000000..2cddf71d7790ce5754868f4fe27d8232dafcd0ac --- /dev/null +++ b/interfaces/kits/cj/src/xattr.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2025 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 OHOS_FILE_FS_XATTR_H +#define OHOS_FILE_FS_XATTR_H + +#include +#include + +#include "cj_common_ffi.h" + +namespace OHOS { +namespace CJSystemapi { +namespace FileFs { +class Xattr final { +public: + static int32_t SetSync(const char *path, const char *key, const char *value); + static std::tuple GetSync(const char *path, const char *key); +}; +} // namespace FileFs +} // namespace CJSystemapi +} // namespace OHOS + +#endif // OHOS_FILE_FS_XATTR_H diff --git a/interfaces/kits/cj/src/xattr_ffi.cpp b/interfaces/kits/cj/src/xattr_ffi.cpp new file mode 100644 index 0000000000000000000000000000000000000000..efcbfc848586dbbd6f05433ee292d5fd9f2db78b --- /dev/null +++ b/interfaces/kits/cj/src/xattr_ffi.cpp @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2025 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 "xattr_ffi.h" +#include "macro.h" +#include "uni_error.h" +#include "xattr.h" + +namespace OHOS { +namespace CJSystemapi { +namespace FileFs { +extern "C" { + +int32_t FfiOHOSFileFsSetXattr(const char *path, const char *key, const char *value) +{ + LOGD("FS_TEST::FfiOHOSFileFsSetXattr"); + if (path == nullptr || key == nullptr || value == nullptr) { + return ERR_INVALID_INSTANCE_CODE; + } + auto state = Xattr::SetSync(path, key, value); + if (state != SUCCESS_CODE) { + LOGE("FS_TEST::FfiOHOSFileFsSetXattr error"); + return GetErrorCode(state); + } + return SUCCESS_CODE; +} + +RetDataCString FfiOHOSFileFsGetXattr(const char *path, const char *key) +{ + LOGD("FS_TEST::FfiOHOSFileFsGetXattr"); + RetDataCString retData = { .code = ERR_INVALID_INSTANCE_CODE, .data = nullptr }; + if (path == nullptr || key == nullptr) { + return retData; + } + auto [state, result] = Xattr::GetSync(path, key); + if (state != SUCCESS_CODE) { + LOGE("FS_TEST::FfiOHOSFileFsGetXattr error"); + retData.code = GetErrorCode(state); + return retData; + } + retData.data = result; + retData.code = SUCCESS_CODE; + return retData; +} + +} +} // namespace FileFs +} // namespace CJSystemapi +} // namespace OHOS diff --git a/interfaces/kits/cj/src/xattr_ffi.h b/interfaces/kits/cj/src/xattr_ffi.h new file mode 100644 index 0000000000000000000000000000000000000000..3bedf71da0296fb7fb1c6173c31f61731b9f68a8 --- /dev/null +++ b/interfaces/kits/cj/src/xattr_ffi.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 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 OHOS_FILE_FS_XATTR_FFI_H +#define OHOS_FILE_FS_XATTR_FFI_H + +#include "cj_common_ffi.h" + +extern "C" { +FFI_EXPORT int32_t FfiOHOSFileFsSetXattr(const char *path, const char *key, const char *value); +FFI_EXPORT RetDataCString FfiOHOSFileFsGetXattr(const char *path, const char *key); +} +#endif // OHOS_FILE_FS_XATTR_FFI_H