diff --git a/interfaces/kits/js/BUILD.gn b/interfaces/kits/js/BUILD.gn index 9334220be9d28e01972e60ed84bec52d044d4e8a..1fa65db68840d11fcd5f4c7a7eba01ee90f6974b 100644 --- a/interfaces/kits/js/BUILD.gn +++ b/interfaces/kits/js/BUILD.gn @@ -693,6 +693,7 @@ ohos_shared_library("ani_fs_class") { "src/mod_fs/properties/ani/truncate_ani.cpp", "src/mod_fs/properties/ani/unlink_ani.cpp", "src/mod_fs/properties/ani/write_ani.cpp", + "src/mod_fs/properties/ani/xattr_ani.cpp", "src/mod_fs/properties/close_core.cpp", "src/mod_fs/properties/copy_file_core.cpp", "src/mod_fs/properties/listfile_core.cpp", @@ -706,6 +707,7 @@ ohos_shared_library("ani_fs_class") { "src/mod_fs/properties/truncate_core.cpp", "src/mod_fs/properties/unlink_core.cpp", "src/mod_fs/properties/write_core.cpp", + "src/mod_fs/properties/xattr_core.cpp", ] deps = [ ":ohos_file_fs_abc_etc", diff --git a/interfaces/kits/js/src/mod_fs/ani/bind_function_class.cpp b/interfaces/kits/js/src/mod_fs/ani/bind_function_class.cpp index 065495c9ade9c4c775ce494fa218d0c382077459..a9eb74249c817a2c865d336a714327f02533e6ef 100644 --- a/interfaces/kits/js/src/mod_fs/ani/bind_function_class.cpp +++ b/interfaces/kits/js/src/mod_fs/ani/bind_function_class.cpp @@ -34,6 +34,7 @@ #include "truncate_ani.h" #include "unlink_ani.h" #include "write_ani.h" +#include "xattr_ani.h" using namespace OHOS::FileManagement::ModuleFileIO::ANI; @@ -76,6 +77,7 @@ static ani_status BindStaticMethods(ani_env *env) ani_native_function { "closeSync", nullptr, reinterpret_cast(CloseAni::CloseSync) }, ani_native_function { "copyFileSync", nullptr, reinterpret_cast(CopyFileAni::CopyFileSync) }, ani_native_function { "doAccessSync", nullptr, reinterpret_cast(AccessAni::AccessSync3) }, + ani_native_function { "getxattrSync", nullptr, reinterpret_cast(XattrAni::GetXattrSync) }, ani_native_function { "listFileSync", nullptr, reinterpret_cast(ListFileAni::ListFileSync) }, ani_native_function { "mkdirSync", "Lstd/core/String;:V", reinterpret_cast(MkdirkAni::MkdirSync0) }, ani_native_function { "mkdirSync", "Lstd/core/String;Z:V", reinterpret_cast(MkdirkAni::MkdirSync1) }, @@ -84,6 +86,7 @@ static ani_status BindStaticMethods(ani_env *env) ani_native_function { "readSync", nullptr, reinterpret_cast(ReadAni::ReadSync) }, ani_native_function { "readTextSync", nullptr, reinterpret_cast(ReadTextAni::ReadTextSync) }, ani_native_function { "rmdirSync", nullptr, reinterpret_cast(RmdirAni::RmdirSync) }, + ani_native_function { "setxattrSync", nullptr, reinterpret_cast(XattrAni::SetXattrSync) }, ani_native_function { "statSync", nullptr, reinterpret_cast(StatAni::StatSync) }, ani_native_function { "truncateSync", nullptr, reinterpret_cast(TruncateAni::TruncateSync) }, ani_native_function { "unlinkSync", nullptr, reinterpret_cast(UnlinkAni::UnlinkSync) }, diff --git a/interfaces/kits/js/src/mod_fs/ani/ets/@ohos.file.fs.ets b/interfaces/kits/js/src/mod_fs/ani/ets/@ohos.file.fs.ets index 67eb95add30a0cd803f0542ae46c90f870189651..0a84ea215a84f610809bc549e6d610554334f3ce 100644 --- a/interfaces/kits/js/src/mod_fs/ani/ets/@ohos.file.fs.ets +++ b/interfaces/kits/js/src/mod_fs/ani/ets/@ohos.file.fs.ets @@ -100,6 +100,22 @@ function closeSync(file: number | File): void { return FileIoImpl.closeSync(file) } +function getxattrSync(path: string, key: string): string { + return FileIoImpl.getxattrSync(path, key) +} + +function getxattr(path: string, key: string): Promise { + return new Promise((resolve: (result: string) => void, reject: (e: BusinessError) => void): void => { + let promise = taskpool.execute(FileIoImpl.getxattrSync, path, key); + promise.then((ret: NullishType): void => { + let result = ret as string; + resolve(result); + }).catch((e: BusinessError): void => { + reject(e); + }); + }); +} + function mkdirSync(path: string): void { return FileIoImpl.mkdirSync(path) } @@ -492,6 +508,22 @@ function stat(file: string | number, callback: AsyncCallback): void }); } +function setxattrSync(path: string, key: string, value: string): void { + return FileIoImpl.setxattrSync(path, key, value) +} + +function setxattr(path: string, key: string, value: string): Promise { + return new Promise((resolve: (result: undefined) => void, reject: (e: BusinessError) => void): void => { + let promise = taskpool.execute((path: string, key: string, value: string): undefined => + FileIoImpl.setxattrSync(path, key, value), path, key, value); + promise.then((ret: NullishType): void => { + resolve(undefined); + }).catch((e: BusinessError): void => { + reject(e as BusinessError); + }); + }); +} + export interface Filter { suffix?: Array; displayName?: Array; @@ -635,6 +667,8 @@ class FileIoImpl { static native copyFileSync(src: string | number, dest: string | number, mode?: number): void; + static native getxattrSync(path: string, key: string): string; + static native listFileSync(path: string, options?: ListFileOptions): string[]; static native mkdirSync(path: string): void; @@ -651,6 +685,8 @@ class FileIoImpl { static native rmdirSync(path: string): void; + static native setxattrSync(path: string, key: string, value: string): void; + static native statSync(file: string | number): Stat; static native truncateSync(file: string | number, len?: number): void; diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/xattr_ani.cpp b/interfaces/kits/js/src/mod_fs/properties/ani/xattr_ani.cpp new file mode 100644 index 0000000000000000000000000000000000000000..47e6d92a513b2e3ed172026caa532a295519dabe --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/ani/xattr_ani.cpp @@ -0,0 +1,98 @@ +/* + * 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_ani.h" + +#include "error_handler.h" +#include "filemgmt_libhilog.h" +#include "type_converter.h" +#include "xattr_core.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { + +void XattrAni::SetXattrSync( + ani_env *env, [[maybe_unused]] ani_class clazz, ani_string path, ani_string key, ani_string value) +{ + auto [pathSucc, pathStr] = TypeConverter::ToUTF8String(env, path); + if (!pathSucc) { + HILOGE("Invalid path"); + ErrorHandler::Throw(env, EINVAL); + return; + } + + auto [keySucc, keyStr] = TypeConverter::ToUTF8String(env, key); + if (!keySucc) { + HILOGE("Invalid key"); + ErrorHandler::Throw(env, EINVAL); + return; + } + + auto [valueSucc, valueStr] = TypeConverter::ToUTF8String(env, value); + if (!valueSucc) { + HILOGE("Invalid value"); + ErrorHandler::Throw(env, EINVAL); + return; + } + + auto ret = XattrCore::DoSetXattr(pathStr, keyStr, valueStr); + if (!ret.IsSuccess()) { + HILOGE("DoSetXattr failed"); + const auto &err = ret.GetError(); + ErrorHandler::Throw(env, err); + return; + } +} + +ani_string XattrAni::GetXattrSync(ani_env *env, [[maybe_unused]] ani_class clazz, ani_string path, ani_string key) +{ + auto [pathSucc, pathStr] = TypeConverter::ToUTF8String(env, path); + if (!pathSucc) { + HILOGE("Invalid path"); + ErrorHandler::Throw(env, EINVAL); + return nullptr; + } + + auto [keySucc, keyStr] = TypeConverter::ToUTF8String(env, key); + if (!keySucc) { + HILOGE("Invalid key"); + ErrorHandler::Throw(env, EINVAL); + return nullptr; + } + + auto ret = XattrCore::DoGetXattr(pathStr, keyStr); + if (!ret.IsSuccess()) { + HILOGE("DoSetXattr failed"); + const auto &err = ret.GetError(); + ErrorHandler::Throw(env, err); + return nullptr; + } + + const auto &res = ret.GetData().value(); + auto [succ, result] = TypeConverter::ToAniString(env, res); + if (!succ) { + HILOGE("Create ani_string error"); + ErrorHandler::Throw(env, UNKNOWN_ERR); + return nullptr; + } + return result; +} + +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/ani/xattr_ani.h b/interfaces/kits/js/src/mod_fs/properties/ani/xattr_ani.h new file mode 100644 index 0000000000000000000000000000000000000000..2bc788d12e55bf19e29f8a2b4ca9a541a4b70e1e --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/ani/xattr_ani.h @@ -0,0 +1,38 @@ +/* + * 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 INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_ANI_XATTR_ANI_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_ANI_XATTR_ANI_H + +#include + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +namespace ANI { + +class XattrAni final { +public: + static void SetXattrSync( + ani_env *env, [[maybe_unused]] ani_class clazz, ani_string path, ani_string key, ani_string value); + static ani_string GetXattrSync(ani_env *env, [[maybe_unused]] ani_class clazz, ani_string path, ani_string key); +}; + +} // namespace ANI +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS + +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_ANI_XATTR_ANI_H \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/xattr_core.cpp b/interfaces/kits/js/src/mod_fs/properties/xattr_core.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ba22e42c7a4c80b9efda1ace164541f35819eff5 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/xattr_core.cpp @@ -0,0 +1,87 @@ +/* + * 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_core.h" + +#include +#include +#include + +#include "file_utils.h" +#include "filemgmt_libhilog.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; +constexpr size_t MAX_XATTR_SIZE = 4096; + +static bool IsIllegalXattr(const char *key, const char *value) +{ + bool isIllegalKey = strnlen(key, MAX_XATTR_SIZE + 1) > MAX_XATTR_SIZE; + if (isIllegalKey) { + HILOGE("key is too long"); + } + bool isIllegalValue = strnlen(value, MAX_XATTR_SIZE + 1) > MAX_XATTR_SIZE; + if (isIllegalValue) { + HILOGE("value is too long"); + } + return isIllegalKey || isIllegalValue; +} + +static int32_t GetXattrCore(const char *path, const char *key, std::shared_ptr result) +{ + ssize_t xAttrSize = getxattr(path, key, nullptr, 0); + if (xAttrSize == -1 || xAttrSize == 0) { + *result = ""; + return ERRNO_NOERR; + } + auto xattrValue = CreateUniquePtr(static_cast(xAttrSize) + 1); + xAttrSize = getxattr(path, key, xattrValue.get(), static_cast(xAttrSize)); + if (xAttrSize == -1) { + return errno; + } + xattrValue[xAttrSize] = '\0'; + *result = std::string(xattrValue.get()); + return ERRNO_NOERR; +} + +FsResult XattrCore::DoSetXattr(const string &path, const string &key, const string &value) +{ + if (IsIllegalXattr(key.c_str(), value.c_str())) { + HILOGE("Invalid xattr value"); + return FsResult::Error(EINVAL); + } + if (setxattr(path.c_str(), key.c_str(), value.c_str(), strnlen(value.c_str(), MAX_XATTR_SIZE), 0) < 0) { + HILOGE("setxattr fail, errno is %{public}d", errno); + return FsResult::Error(errno); + } + return FsResult::Success(); +} + +FsResult XattrCore::DoGetXattr(const string &path, const string &key) +{ + auto result = make_shared(); + int32_t ret = GetXattrCore(path.c_str(), key.c_str(), result); + if (ret != ERRNO_NOERR) { + HILOGE("Invalid getxattr"); + return FsResult::Error(ret); + } + return FsResult::Success(move(*result)); +} + +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/js/src/mod_fs/properties/xattr_core.h b/interfaces/kits/js/src/mod_fs/properties/xattr_core.h new file mode 100644 index 0000000000000000000000000000000000000000..71ca376e91e7ff8b649fcbc4f6ad327f0b8a7bf2 --- /dev/null +++ b/interfaces/kits/js/src/mod_fs/properties/xattr_core.h @@ -0,0 +1,35 @@ +/* + * 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 INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_XATTR_CORE_H +#define INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_XATTR_CORE_H + +#include "filemgmt_libfs.h" +#include "fs_utils.h" + +namespace OHOS { +namespace FileManagement { +namespace ModuleFileIO { +using namespace std; +class XattrCore final { +public: + static FsResult DoSetXattr(const string &path, const string &key, const string &value); + static FsResult DoGetXattr(const string &path, const string &key); +}; + +} // namespace ModuleFileIO +} // namespace FileManagement +} // namespace OHOS +#endif // INTERFACES_KITS_JS_SRC_MOD_FS_PROPERTIES_XATTR_CORE_H \ No newline at end of file