1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "xattr.h"
17 #include <cstring>
18 #include <sys/xattr.h>
19 #include "macro.h"
20 #include "securec.h"
21
22 using namespace std;
23
24 namespace {
25 constexpr size_t MAX_XATTR_SIZE = 4096;
26
CreateCString(string str)27 char* CreateCString(string str)
28 {
29 auto ret = static_cast<char*>(malloc(str.size() + 1));
30 if (ret == nullptr) {
31 return nullptr;
32 }
33 if (strcpy_s(ret, str.size() + 1, str.c_str()) != 0) {
34 free(ret);
35 return nullptr;
36 }
37 return ret;
38 }
39
IsIllegalXattr(const char * key,const char * value)40 bool IsIllegalXattr(const char *key, const char *value)
41 {
42 bool isIllegalKey = strnlen(key, MAX_XATTR_SIZE + 1) > MAX_XATTR_SIZE;
43 if (isIllegalKey) {
44 LOGE("key is too loog");
45 }
46 bool isIllegalValue = strnlen(value, MAX_XATTR_SIZE + 1) > MAX_XATTR_SIZE;
47 if (isIllegalValue) {
48 LOGE("value is too loog");
49 }
50 return isIllegalKey || isIllegalValue;
51 }
52 }
53
54 namespace OHOS {
55 namespace CJSystemapi {
56 namespace FileFs {
57
SetSync(const char * path,const char * key,const char * value)58 int32_t Xattr::SetSync(const char *path, const char *key, const char *value)
59 {
60 if (IsIllegalXattr(key, value)) {
61 return EINVAL;
62 }
63 if (setxattr(path, key, value, strnlen(value, MAX_XATTR_SIZE), 0) < 0) {
64 LOGE("setxattr fail, errno is %{public}d", errno);
65 return errno;
66 }
67 return SUCCESS_CODE;
68 }
69
GetSync(const char * path,const char * key)70 tuple<int32_t, char*> Xattr::GetSync(const char *path, const char *key)
71 {
72 ssize_t xAttrSize = getxattr(path, key, nullptr, 0);
73 if (xAttrSize == -1 || xAttrSize == 0) {
74 auto result = CreateCString("");
75 if (result == nullptr) {
76 return { ENOMEM, nullptr };
77 }
78 return { SUCCESS_CODE, result };
79 }
80 auto xAttrValue = static_cast<char*>(malloc(static_cast<long>(xAttrSize) + 1));
81 if (xAttrValue == nullptr) {
82 return { ENOMEM, nullptr };
83 }
84 xAttrSize = getxattr(path, key, xAttrValue, static_cast<size_t>(xAttrSize));
85 if (xAttrSize == -1) {
86 free(xAttrValue);
87 return { errno, nullptr };
88 }
89 xAttrValue[xAttrSize] = '\0';
90 return { SUCCESS_CODE, xAttrValue };
91 }
92
93 } // namespace FileFs
94 } // namespace CJSystemapi
95 } // namespace OHOS
96