未验证 提交 51900aa4 编写于 作者: O openharmony_ci 提交者: Gitee

!69 移动kv_store

Merge pull request !69 from zhoushilin/master
../../../foundation/distributeddatamgr/appdatamgr/frameworks/innerkitsimpl/kv_store
\ No newline at end of file
# Copyright (c) 2020 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.
import("//build/lite/config/component/lite_component.gni")
lite_component("kv_store") {
features = [ "src:utils_kv_store" ]
}
/*
* Copyright (c) 2020 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 KV_STORE_ENV_API_H
#define KV_STORE_ENV_API_H
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif /* __cplusplus */
int UtilsSetEnv(const char* path);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif // KV_STORE_ENV_API_H
\ No newline at end of file
# Copyright (c) 2020 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.
declare_args() {
enable_ohos_utils_native_lite_kv_store_use_posix_kv_api = true
}
if (ohos_kernel_type == "liteos_m") {
static_library("utils_kv_store") {
sources = [ "kvstore_common/kvstore_common.c" ]
if (enable_ohos_utils_native_lite_kv_store_use_posix_kv_api) {
sources += [ "kvstore_impl_posix/kv_store.c" ]
} else {
sources += [ "kvstore_impl_hal/kv_store.c" ]
}
include_dirs = [
"//utils/native/lite/include",
"kvstore_common",
"//utils/native/lite/kv_store/innerkits",
]
}
} else {
shared_library("utils_kv_store") {
cflags = [ "-Wall" ]
cflags_cc = cflags
sources = [
"kvstore_common/kvstore_common.c",
"kvstore_impl_posix/kv_store.c",
]
include_dirs = [
"//utils/native/lite/include",
"kvstore_common",
"//third_party/bounds_checking_function/include",
"//utils/native/lite/kv_store/innerkits",
]
public_deps = [ "//third_party/bounds_checking_function:libsec_shared" ]
}
}
/*
* Copyright (c) 2020 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 "kvstore_common.h"
#include <ctype.h>
#include <securec.h>
#include <stdlib.h>
#include "ohos_errno.h"
#ifdef FEATURE_KV_CACHE
static KvItem* g_itemHeader = NULL;
static KvItem* g_itemTail = NULL;
static int g_sum = 0;
#endif
boolean IsValidChar(const char ch)
{
if (islower(ch) || isdigit(ch) || (ch == '_') || (ch == '.')) {
return TRUE;
}
return FALSE;
}
boolean IsValidValue(const char* value, unsigned int len)
{
if (value == NULL) {
return FALSE;
}
size_t valueLen = strnlen(value, MAX_VALUE_LEN);
if ((valueLen == 0) || (valueLen >= MAX_VALUE_LEN) || (valueLen >= len)) {
return FALSE;
}
return TRUE;
}
boolean IsValidKey(const char* key)
{
if (!IsValidValue(key, MAX_KEY_LEN)) {
return FALSE;
}
size_t keyLen = strnlen(key, MAX_KEY_LEN);
for (size_t i = 0; i < keyLen; i++) {
if (!IsValidChar(key[i])) {
return FALSE;
}
}
return TRUE;
}
#ifdef FEATURE_KV_CACHE
static void FreeItem(KvItem* item)
{
if (item == NULL) {
return;
}
if (item->key != NULL) {
free(item->key);
}
if (item->value != NULL) {
free(item->value);
}
free(item);
}
void DeleteKVCache(const char* key)
{
if (key == NULL || g_itemHeader == NULL) {
return;
}
KvItem* item = g_itemHeader;
while (strcmp(key, item->key) != 0) {
item = item->next;
if (item == NULL) {
return;
}
}
g_sum--;
if (g_sum == 0) {
g_itemHeader = NULL;
g_itemTail = NULL;
} else if (item == g_itemHeader) {
g_itemHeader = item->next;
g_itemHeader->prev = NULL;
} else if (item == g_itemTail) {
g_itemTail = item->prev;
g_itemTail->next = NULL;
} else {
item->prev->next = item->next;
item->next->prev = item->prev;
}
FreeItem(item);
}
void AddKVCache(const char* key, const char* value, boolean isNew)
{
if (key == NULL || value == NULL) {
return;
}
size_t keyLen = strnlen(key, MAX_KEY_LEN);
size_t valueLen = strnlen(value, MAX_VALUE_LEN);
if ((keyLen >= MAX_KEY_LEN) || (valueLen >= MAX_VALUE_LEN)) {
return;
}
if (isNew) {
DeleteKVCache(key);
}
KvItem* item = (KvItem *)malloc(sizeof(KvItem));
if (item == NULL) {
return;
}
(void)memset_s(item, sizeof(KvItem), 0, sizeof(KvItem));
item->key = (char *)malloc(keyLen + 1);
item->value = (char *)malloc(valueLen + 1);
if ((item->key == NULL) || (item->value == NULL)) {
FreeItem(item);
return;
}
if ((strcpy_s(item->key, keyLen + 1, key) != EOK) ||
(strcpy_s(item->value, valueLen + 1, value) != EOK)) {
FreeItem(item);
return;
}
item->prev = NULL;
item->next = NULL;
if (g_itemHeader == NULL) {
g_itemHeader = item;
g_itemTail = item;
g_sum++;
return;
}
item->next = g_itemHeader;
g_itemHeader->prev = item;
g_itemHeader = item;
g_sum++;
while (g_sum > MAX_CACHE_SIZE) {
KvItem* needDel = g_itemTail;
g_itemTail = g_itemTail->prev;
FreeItem(needDel);
g_itemTail->next = NULL;
g_sum--;
}
}
int GetValueByCache(const char* key, char* value, unsigned int maxLen)
{
if (key == NULL || value == NULL || g_itemHeader == NULL) {
return EC_FAILURE;
}
KvItem* item = g_itemHeader;
while (strcmp(key, item->key) != 0) {
item = item->next;
if (item == NULL) {
return EC_FAILURE;
}
}
size_t valueLen = strnlen(item->value, MAX_VALUE_LEN);
if (valueLen >= MAX_VALUE_LEN) {
return EC_FAILURE;
}
if ((valueLen >= maxLen) || (strcpy_s(value, maxLen, item->value) != EOK)) {
return EC_FAILURE;
}
return EC_SUCCESS;
}
int ClearKVCacheInner(void)
{
if (g_itemHeader == NULL) {
return EC_SUCCESS;
}
KvItem* item = g_itemHeader;
while (item != NULL) {
KvItem* temp = item;
item = item->next;
FreeItem(temp);
g_sum--;
}
g_itemHeader = NULL;
g_itemTail = NULL;
return (g_sum != 0) ? EC_FAILURE : EC_SUCCESS;
}
#endif
\ No newline at end of file
/*
* Copyright (c) 2020 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 KV_STORE_COMMON_H
#define KV_STORE_COMMON_H
#include "ohos_types.h"
#include "utils_config.h"
#define MAX_KEY_LEN 32
#define MAX_VALUE_LEN 128
boolean IsValidChar(const char ch);
boolean IsValidValue(const char* value, unsigned int len);
boolean IsValidKey(const char* key);
#ifdef FEATURE_KV_CACHE
typedef struct KvItem_ {
char* key;
char* value;
struct KvItem_* next;
struct KvItem_* prev;
} KvItem;
void DeleteKVCache(const char* key);
void AddKVCache(const char* key, const char* value, boolean isNew);
int GetValueByCache(const char* key, char* value, unsigned int maxLen);
int ClearKVCacheInner(void);
#endif
#endif // KV_STORE_COMMON_H
\ No newline at end of file
/*
* Copyright (c) 2020 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 "kv_store.h"
#include <ctype.h>
#include <securec.h>
#include <stdlib.h>
#include "kvstore_common.h"
#include "ohos_errno.h"
#include "ohos_types.h"
#include "utils_config.h"
#include "utils_file.h"
#define MAX_GET_VALUE_LEN 0x7FFFFFFF
#define KV_SUM_FILE "KV_FILE_SUM"
#define KV_SUM_INDEX 4
static int GetValueByFile(const char* key, char* value, unsigned int len)
{
unsigned int valueLen = 0;
if (UtilsFileStat(key, &valueLen) != EC_SUCCESS) {
return EC_FAILURE;
}
if (valueLen >= len) {
return EC_FAILURE;
}
int fd = UtilsFileOpen(key, O_RDONLY_FS, 0);
if (fd < 0) {
return EC_FAILURE;
}
int ret = UtilsFileRead(fd, value, valueLen);
UtilsFileClose(fd);
fd = -1;
if (ret < 0) {
return EC_FAILURE;
}
value[valueLen] = '\0';
return valueLen;
}
static int SetValueToFile(const char* key, const char* value)
{
int fd = UtilsFileOpen(key, O_RDWR_FS | O_CREAT_FS | O_TRUNC_FS, 0);
if (fd < 0) {
return EC_FAILURE;
}
int ret = UtilsFileWrite(fd, value, strlen(value));
UtilsFileClose(fd);
fd = -1;
return (ret < 0) ? EC_FAILURE : EC_SUCCESS;
}
static int GetCurrentItem(void)
{
int fd = UtilsFileOpen(KV_SUM_FILE, O_RDWR_FS, 0);
if (fd < 0) {
return 0;
}
char value[KV_SUM_INDEX] = {0};
int ret = UtilsFileRead(fd, value, KV_SUM_INDEX);
UtilsFileClose(fd);
fd = -1;
return (ret < 0) ? 0 : atoi(value);
}
static int SetCurrentItem(const int num)
{
char value[KV_SUM_INDEX] = {0};
if (sprintf_s(value, KV_SUM_INDEX, "%d", num) < 0) {
return EC_FAILURE;
}
int fd = UtilsFileOpen(KV_SUM_FILE, O_RDWR_FS | O_CREAT_FS, 0);
if (fd < 0) {
return EC_FAILURE;
}
int ret = UtilsFileWrite(fd, value, KV_SUM_INDEX);
UtilsFileClose(fd);
fd = -1;
return (ret < 0) ? EC_FAILURE : EC_SUCCESS;
}
static boolean NewItem(const char* key)
{
int fd = UtilsFileOpen(key, O_RDONLY_FS, 0);
if (fd < 0) {
return TRUE;
}
UtilsFileClose(fd);
return FALSE;
}
int UtilsGetValue(const char* key, char* value, unsigned int len)
{
if (!IsValidKey(key) || (value == NULL) || (len > MAX_GET_VALUE_LEN)) {
return EC_INVALID;
}
#ifdef FEATURE_KV_CACHE
if (GetValueByCache(key, value, len) == EC_SUCCESS) {
return EC_SUCCESS;
}
#endif
int ret = GetValueByFile(key, value, len);
if (ret < 0) {
return EC_FAILURE;
}
#ifdef FEATURE_KV_CACHE
AddKVCache(key, value, FALSE);
#endif
return ret;
}
int UtilsSetValue(const char* key, const char* value)
{
if (!IsValidKey(key) || !IsValidValue(value, MAX_VALUE_LEN)) {
return EC_INVALID;
}
int currentNum = GetCurrentItem();
boolean newItem = NewItem(key);
if ((currentNum >= MAX_KV_SUM) && newItem) {
return EC_FAILURE;
}
int ret = SetValueToFile(key, value);
if (ret == EC_SUCCESS) {
#ifdef FEATURE_KV_CACHE
AddKVCache(key, value, TRUE);
#endif
if (newItem) {
currentNum++;
}
}
return SetCurrentItem(currentNum);
}
int UtilsDeleteValue(const char* key)
{
if (!IsValidKey(key)) {
return EC_INVALID;
}
#ifdef FEATURE_KV_CACHE
DeleteKVCache(key);
#endif
int ret = UtilsFileDelete(key);
if (ret == EC_SUCCESS) {
ret = SetCurrentItem(GetCurrentItem() - 1);
}
return ret;
}
#ifdef FEATURE_KV_CACHE
int ClearKVCache(void)
{
return ClearKVCacheInner();
}
#endif
int UtilsSetEnv(const char* path)
{
return EC_SUCCESS;
}
\ No newline at end of file
/*
* Copyright (c) 2020 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 "kv_store.h"
#include <ctype.h>
#include <dirent.h>
#include <fcntl.h>
#include <limits.h>
#include <pthread.h>
#include <securec.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "kvstore_common.h"
#include "kvstore_env.h"
#include "ohos_errno.h"
#include "ohos_types.h"
#include "utils_config.h"
#define KVSTORE_PATH "kvstore"
#define MAX_KEY_PATH 256
#define MAX_GET_VALUE_LEN 0x7FFFFFFF
static pthread_mutex_t g_kvGlobalMutex = PTHREAD_MUTEX_INITIALIZER;
static int g_kvSum = 0;
static boolean g_getKvSum = FALSE;
static char g_dataPath[MAX_KEY_PATH + 1] = {0};
static int GetResolvedPath(const char* dataPath, const char* key, char* resolvedPath, unsigned int len)
{
char* keyPath = (char *)malloc(MAX_KEY_PATH + 1);
if (keyPath == NULL) {
return EC_FAILURE;
}
if (sprintf_s(keyPath, MAX_KEY_PATH + 1, "%s/%s/%s", dataPath, KVSTORE_PATH, key) < 0) {
free(keyPath);
return EC_FAILURE;
}
if (realpath(keyPath, resolvedPath) != NULL) {
free(keyPath);
return EC_SUCCESS;
}
if (errno == ENOENT) {
if (strncpy_s(resolvedPath, len, keyPath, strlen(keyPath)) == EOK) {
free(keyPath);
return EC_SUCCESS;
}
}
free(keyPath);
return EC_FAILURE;
}
static int GetValueByFile(const char* dataPath, const char* key, char* value, unsigned int len)
{
char* keyPath = (char *)malloc(PATH_MAX + 1);
if (keyPath == NULL) {
return EC_FAILURE;
}
if (GetResolvedPath(dataPath, key, keyPath, PATH_MAX + 1) != EC_SUCCESS) {
free(keyPath);
return EC_FAILURE;
}
struct stat info = {0};
if (stat(keyPath, &info) != F_OK) {
free(keyPath);
return EC_FAILURE;
}
if (info.st_size >= len) {
free(keyPath);
return EC_FAILURE;
}
int fd = open(keyPath, O_RDONLY, S_IRUSR);
free(keyPath);
keyPath = NULL;
if (fd < 0) {
return EC_FAILURE;
}
int ret = read(fd, value, info.st_size);
close(fd);
fd = -1;
if (ret < 0) {
return EC_FAILURE;
}
value[info.st_size] = '\0';
return info.st_size;
}
static int SetValueToFile(const char* dataPath, const char* key, const char* value)
{
char* keyPath = (char *)malloc(PATH_MAX + 1);
if (keyPath == NULL) {
return EC_FAILURE;
}
if (GetResolvedPath(dataPath, key, keyPath, PATH_MAX + 1) != EC_SUCCESS) {
free(keyPath);
return EC_FAILURE;
}
int fd = open(keyPath, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
free(keyPath);
keyPath = NULL;
if (fd < 0) {
return EC_FAILURE;
}
int ret = write(fd, value, strlen(value));
close(fd);
fd = -1;
return (ret < 0) ? EC_FAILURE : EC_SUCCESS;
}
static int DeleteValueFromFile(const char* dataPath, const char* key)
{
char* keyPath = (char *)malloc(MAX_KEY_PATH + 1);
if (keyPath == NULL) {
return EC_FAILURE;
}
if (sprintf_s(keyPath, MAX_KEY_PATH + 1, "%s/%s/%s", dataPath, KVSTORE_PATH, key) < 0) {
free(keyPath);
return EC_FAILURE;
}
int ret = unlink(keyPath);
free(keyPath);
return ret;
}
static int InitKv(const char* dataPath)
{
if (dataPath == NULL) {
return EC_FAILURE;
}
char* kvPath = (char *)malloc(MAX_KEY_PATH + 1);
if (kvPath == NULL) {
return EC_FAILURE;
}
if (sprintf_s(kvPath, MAX_KEY_PATH + 1, "%s/%s", dataPath, KVSTORE_PATH) < 0) {
free(kvPath);
return EC_FAILURE;
}
if (access(kvPath, F_OK) == F_OK) {
free(kvPath);
return EC_SUCCESS;
}
if (mkdir(kvPath, S_IRUSR | S_IWUSR | S_IXUSR) != F_OK) {
free(kvPath);
return EC_FAILURE;
}
free(kvPath);
return EC_SUCCESS;
}
static int GetCurrentItem(const char* dataPath)
{
char kvPath[MAX_KEY_PATH + 1] = {0};
if (sprintf_s(kvPath, MAX_KEY_PATH + 1, "%s/%s", dataPath, KVSTORE_PATH) < 0) {
return EC_FAILURE;
}
DIR* fileDir = opendir(kvPath);
if (fileDir == NULL) {
return EC_FAILURE;
}
struct dirent* dir = readdir(fileDir);
int sum = 0;
while (dir != NULL) {
char fullPath[MAX_KEY_PATH + 1] = {0};
struct stat info = {0};
if (sprintf_s(fullPath, MAX_KEY_PATH + 1, "%s/%s", kvPath, dir->d_name) < 0) {
closedir(fileDir);
return EC_FAILURE;
}
if (stat(fullPath, &info) != 0) {
closedir(fileDir);
return EC_FAILURE;
}
if (S_ISREG(info.st_mode)) {
sum++;
}
dir = readdir(fileDir);
}
closedir(fileDir);
return sum;
}
static boolean NewItem(const char* dataPath, const char* key)
{
char* keyPath = (char *)malloc(MAX_KEY_PATH + 1);
if (keyPath == NULL) {
return FALSE;
}
if (sprintf_s(keyPath, MAX_KEY_PATH + 1, "%s/%s/%s", dataPath, KVSTORE_PATH, key) < 0) {
free(keyPath);
return FALSE;
}
if (access(keyPath, F_OK) == F_OK) {
free(keyPath);
return FALSE;
}
free(keyPath);
return TRUE;
}
int UtilsGetValue(const char* key, char* value, unsigned int len)
{
if (!IsValidKey(key) || (value == NULL) || (len > MAX_GET_VALUE_LEN)) {
return EC_INVALID;
}
pthread_mutex_lock(&g_kvGlobalMutex);
const char* dataPath = g_dataPath;
if (dataPath == NULL) {
pthread_mutex_unlock(&g_kvGlobalMutex);
return EC_FAILURE;
}
#ifdef FEATURE_KV_CACHE
if (GetValueByCache(key, value, len) == EC_SUCCESS) {
pthread_mutex_unlock(&g_kvGlobalMutex);
return EC_SUCCESS;
}
#endif
int ret = GetValueByFile(dataPath, key, value, len);
if (ret < 0) {
pthread_mutex_unlock(&g_kvGlobalMutex);
return EC_FAILURE;
}
#ifdef FEATURE_KV_CACHE
AddKVCache(key, value, FALSE);
#endif
pthread_mutex_unlock(&g_kvGlobalMutex);
return ret;
}
int UtilsSetValue(const char* key, const char* value)
{
if (!IsValidKey(key) || !IsValidValue(value, MAX_VALUE_LEN)) {
return EC_INVALID;
}
pthread_mutex_lock(&g_kvGlobalMutex);
const char* dataPath = g_dataPath;
int ret = InitKv(dataPath);
if (ret != EC_SUCCESS) {
g_getKvSum = FALSE;
pthread_mutex_unlock(&g_kvGlobalMutex);
return EC_FAILURE;
}
if (!g_getKvSum) {
g_kvSum = GetCurrentItem(dataPath);
if (g_kvSum < 0) {
pthread_mutex_unlock(&g_kvGlobalMutex);
return EC_FAILURE;
}
g_getKvSum = TRUE;
}
boolean newItem = NewItem(dataPath, key);
if ((g_kvSum >= MAX_KV_SUM) && newItem) {
pthread_mutex_unlock(&g_kvGlobalMutex);
return EC_FAILURE;
}
ret = SetValueToFile(dataPath, key, value);
if (ret == EC_SUCCESS) {
#ifdef FEATURE_KV_CACHE
AddKVCache(key, value, TRUE);
#endif
if (newItem) {
g_kvSum++;
}
}
pthread_mutex_unlock(&g_kvGlobalMutex);
return ret;
}
int UtilsDeleteValue(const char* key)
{
if (!IsValidKey(key)) {
return EC_INVALID;
}
pthread_mutex_lock(&g_kvGlobalMutex);
const char* dataPath = g_dataPath;
if (dataPath == NULL) {
pthread_mutex_unlock(&g_kvGlobalMutex);
return EC_FAILURE;
}
#ifdef FEATURE_KV_CACHE
DeleteKVCache(key);
#endif
int ret = DeleteValueFromFile(dataPath, key);
if (ret == EC_SUCCESS) {
g_kvSum--;
}
pthread_mutex_unlock(&g_kvGlobalMutex);
return ret;
}
#ifdef FEATURE_KV_CACHE
int ClearKVCache(void)
{
pthread_mutex_lock(&g_kvGlobalMutex);
int ret = ClearKVCacheInner();
pthread_mutex_unlock(&g_kvGlobalMutex);
return ret;
}
#endif
int UtilsSetEnv(const char* path)
{
if (path == NULL) {
return EC_FAILURE;
}
pthread_mutex_lock(&g_kvGlobalMutex);
int ret = strcpy_s(g_dataPath, MAX_KEY_PATH + 1, path);
pthread_mutex_unlock(&g_kvGlobalMutex);
return (ret != EOK) ? EC_FAILURE : EC_SUCCESS;
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册