mirror of
https://github.com/openharmony/startup_init_lite.git
synced 2026-07-19 17:07:55 -04:00
@@ -34,7 +34,7 @@
|
||||
#define MAX_SOCKET_ENV_PREFIX_LEN 64
|
||||
#define MAX_SOCKET_DIR_LEN 128
|
||||
|
||||
static int GetControlFromEnv(char *path, int length)
|
||||
static int GetControlFromEnv(const char *path, int length)
|
||||
{
|
||||
if (path == NULL || length <= 0) {
|
||||
return -1;
|
||||
|
||||
@@ -52,7 +52,7 @@ struct CmdArgs {
|
||||
|
||||
int GetParamValue(const char *symValue, char *paramValue, unsigned int paramLen);
|
||||
struct CmdArgs* GetCmd(const char *cmdContent, const char *delim, int argsCount);
|
||||
void FreeCmd(struct CmdArgs **cmd);
|
||||
void FreeCmd(struct CmdArgs *cmd);
|
||||
|
||||
void ParseCmdLine(const char* cmdStr, CmdLine* resCmd);
|
||||
void DoCmd(const CmdLine* curCmd);
|
||||
|
||||
@@ -12,8 +12,12 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef BASE_STARTUP_INITLITE_IMPORT_H
|
||||
#define BASE_STARTUP_INITLITE_IMPORT_H
|
||||
#include "cJSON.h"
|
||||
void ParseAllImports(cJSON *root);
|
||||
#endif
|
||||
|
||||
#ifndef BASE_STARTUP_INITLITE_IMPORT_H
|
||||
#define BASE_STARTUP_INITLITE_IMPORT_H
|
||||
|
||||
#include "cJSON.h"
|
||||
|
||||
void ParseAllImports(const cJSON *root);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -23,8 +23,7 @@
|
||||
|
||||
#define MAX_SOCK_NAME_LEN 16
|
||||
#define SOCK_OPT_NUMS 6
|
||||
enum SockOptionTab
|
||||
{
|
||||
enum SockOptionTab {
|
||||
SERVICE_SOCK_NAME = 0,
|
||||
SERVICE_SOCK_TYPE,
|
||||
SERVICE_SOCK_PERM,
|
||||
@@ -34,8 +33,7 @@ enum SockOptionTab
|
||||
};
|
||||
|
||||
struct ServiceSocket;
|
||||
struct ServiceSocket
|
||||
{
|
||||
struct ServiceSocket {
|
||||
char *name; // service name
|
||||
int type; // socket type
|
||||
uid_t uid; // uid
|
||||
|
||||
@@ -25,6 +25,7 @@ extern "C" {
|
||||
#define BINARY_BASE 2
|
||||
#define OCTAL_BASE 8
|
||||
#define DECIMAL_BASE 10
|
||||
#define ARRAY_LENGTH(array) (sizeof((array)) / sizeof((array)[0]))
|
||||
|
||||
int DecodeUid(const char *name);
|
||||
void CheckAndCreateDir(const char *fileName);
|
||||
|
||||
@@ -105,7 +105,7 @@ void PostParamTrigger(const char *name, const char *value);
|
||||
* 解析trigger文件。
|
||||
*
|
||||
*/
|
||||
int ParseTriggerConfig(cJSON *fileRoot);
|
||||
int ParseTriggerConfig(const cJSON *fileRoot);
|
||||
|
||||
/**
|
||||
* 对Init接口
|
||||
@@ -126,4 +126,4 @@ int SystemTraversalParam(void (*traversalParameter)(ParamHandle handle, void* co
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -82,7 +82,7 @@ void EnableDevKmsg(void)
|
||||
if (fd < 0) {
|
||||
return;
|
||||
}
|
||||
char *kmsgStatus = "on";
|
||||
const char *kmsgStatus = "on";
|
||||
write(fd, kmsgStatus, strlen(kmsgStatus) + 1);
|
||||
close(fd);
|
||||
fd = -1;
|
||||
|
||||
@@ -117,6 +117,13 @@ void EnableDevKmsg(void);
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define INIT_CHECK_ONLY_ELOG(ret, format, ...) \
|
||||
do { \
|
||||
if (!(ret)) { \
|
||||
INIT_LOGE(format, ##__VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
|
||||
@@ -79,7 +79,8 @@ static void OnConnection(uv_connect_t *connect, int status)
|
||||
RequestNode *request = ParamEntry(connect, RequestNode, connect);
|
||||
PARAM_LOGD("Connect to server handle %p", &(request->handle));
|
||||
uv_buf_t buf = uv_buf_init((char*)&request->msg, request->msg.contentSize + sizeof(request->msg));
|
||||
int ret = uv_write2(&request->wr, (uv_stream_t*)&(request->handle), &buf, 1, (uv_stream_t*)&(request->handle), OnWrite);
|
||||
int ret = uv_write2(&request->wr, (uv_stream_t*)&(request->handle), &buf, 1,
|
||||
(uv_stream_t*)&(request->handle), OnWrite);
|
||||
PARAM_CHECK(ret >= 0, return, "Failed to uv_write2 porperty");
|
||||
|
||||
// read result
|
||||
@@ -108,9 +109,9 @@ int SystemSetParameter(const char *name, const char *value)
|
||||
PARAM_CHECK(name != NULL && value != NULL, return -1, "Invalid param");
|
||||
int ret = CheckParamName(name, 0);
|
||||
PARAM_CHECK(ret == 0, return ret, "Illegal param name");
|
||||
|
||||
u_int32_t len = 2;
|
||||
PARAM_LOGD("StartRequest %s", name);
|
||||
u_int32_t msgSize = sizeof(RequestMsg) + strlen(name) + strlen(value) + 2;
|
||||
u_int32_t msgSize = sizeof(RequestMsg) + strlen(name) + strlen(value) + len;
|
||||
RequestNode *request = (RequestNode *)malloc(sizeof(RequestNode) + msgSize);
|
||||
PARAM_CHECK(request != NULL, return -1, "Failed to malloc for connect");
|
||||
|
||||
|
||||
@@ -41,7 +41,6 @@ typedef enum {
|
||||
PARAM_CODE_NOT_INIT
|
||||
} PARAM_CODE;
|
||||
|
||||
#define IS_READY_ONLY(name) strncmp((name), "ro.", strlen("ro.")) == 0
|
||||
#define LABEL_STRING_LEN 128
|
||||
|
||||
#ifdef STARTUP_LOCAL
|
||||
@@ -75,16 +74,16 @@ typedef enum {
|
||||
}
|
||||
|
||||
#define futex(addr1, op, val, rel, addr2, val3) \
|
||||
syscall(SYS_futex, addr1, op, val, rel, addr2, val3)
|
||||
syscall(SYS_futex, addr1, op, val, rel, addr2, val3)
|
||||
#define futex_wait_always(addr1) \
|
||||
syscall(SYS_futex, addr1, FUTEX_WAIT, *(int*)(addr1), 0, 0, 0)
|
||||
syscall(SYS_futex, addr1, FUTEX_WAIT, *(int*)(addr1), 0, 0, 0)
|
||||
#define futex_wake_single(addr1) \
|
||||
syscall(SYS_futex, addr1, FUTEX_WAKE, 1, 0, 0, 0)
|
||||
syscall(SYS_futex, addr1, FUTEX_WAKE, 1, 0, 0, 0)
|
||||
|
||||
typedef struct UserCred {
|
||||
pid_t pid;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
pid_t pid;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
} UserCred;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -39,12 +39,10 @@ extern "C" {
|
||||
#define FILENAME_LEN_MAX 255
|
||||
#define TRIE_DATA_LEN_MAX 128
|
||||
|
||||
#define NODE_INDEX unsigned int
|
||||
|
||||
#define TRIE_NODE_HEADER \
|
||||
atomic_uint_least32_t serial; \
|
||||
NODE_INDEX left; \
|
||||
NODE_INDEX right;
|
||||
unsigned int left; \
|
||||
unsigned int right;
|
||||
|
||||
#define DATA_ENTRY_KEY_LEN(entry) (entry)->dataLength >> TRIE_SERIAL_KEY_LEN_OFFSET
|
||||
#define DATA_ENTRY_DATA_LEN(entry) (((entry)->dataLength >> TRIE_SERIAL_DATA_LEN_OFFSET) & 0x00FF)
|
||||
@@ -64,9 +62,9 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
TRIE_NODE_HEADER;
|
||||
NODE_INDEX child;
|
||||
NODE_INDEX labelIndex;
|
||||
NODE_INDEX dataIndex;
|
||||
unsigned int child;
|
||||
unsigned int labelIndex;
|
||||
unsigned int dataIndex;
|
||||
char key[0];
|
||||
} TrieDataNode;
|
||||
|
||||
@@ -104,9 +102,9 @@ int CompareTrieDataNode(TrieNode *node, const char *key, u_int32_t keyLen);
|
||||
u_int32_t AllocateTrieDataNode(WorkSpace *workSpace, const char *key, u_int32_t keyLen);
|
||||
|
||||
u_int32_t GetTrieNodeOffset(WorkSpace *workSpace, const TrieNode *current);
|
||||
TrieNode *GetTrieNode(WorkSpace *workSpace, NODE_INDEX *index);
|
||||
TrieNode *GetTrieNode(WorkSpace *workSpace, const unsigned int *index);
|
||||
u_int32_t GetTrieKeyLen(TrieNode *current);
|
||||
void SaveIndex(NODE_INDEX *index, u_int32_t offset);
|
||||
void SaveIndex(unsigned int *index, u_int32_t offset);
|
||||
TrieDataNode *AddTrieDataNode(WorkSpace *workSpace, const char *key, u_int32_t keyLen);
|
||||
TrieDataNode *AddToSubTrie(WorkSpace *workSpace, TrieDataNode *dataNode, const char *key, u_int32_t keyLen);
|
||||
TrieDataNode *FindSubTrie(WorkSpace *workSpace, TrieDataNode *dataNode, const char *key, u_int32_t keyLen);
|
||||
@@ -135,4 +133,4 @@ u_int32_t GetDataSerial(const DataEntry *entry);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif // BASE_STARTUP_PARAM_TRIE_H
|
||||
#endif // BASE_STARTUP_PARAM_TRIE_H
|
||||
|
||||
@@ -95,11 +95,12 @@ typedef struct TriggerWorkSpace {
|
||||
} TriggerWorkSpace;
|
||||
|
||||
int InitTriggerWorkSpace(TriggerWorkSpace *workSpace);
|
||||
int ParseTrigger(TriggerWorkSpace *workSpace, cJSON *triggerItem);
|
||||
int ParseTrigger(TriggerWorkSpace *workSpace, const cJSON *triggerItem);
|
||||
|
||||
typedef int (*TRIGGER_MATCH)(LogicCalculator *calculator, TriggerNode *trigger, const char *content, u_int32_t contentSize);
|
||||
typedef int (*TRIGGER_MATCH)(LogicCalculator *calculator, TriggerNode *trigger, const char *content,
|
||||
u_int32_t contentSize);
|
||||
typedef int (*PARAM_CHECK_DONE)(TriggerNode *trigger, u_int32_t index);
|
||||
typedef int (*CMD_EXECUTE) (TriggerNode *trigger, const char *cmdName, const char *command);
|
||||
typedef int (*CMD_EXECUTE) (const TriggerNode *trigger, const char *cmdName, const char *command);
|
||||
|
||||
TriggerNode *GetTriggerByName(TriggerWorkSpace *workSpace, const char *triggerName, u_int32_t *triggerIndex);
|
||||
int ExecuteTrigger(TriggerWorkSpace *workSpace, TriggerNode *trigger, CMD_EXECUTE cmdExecuter);
|
||||
@@ -111,7 +112,7 @@ int CheckAndExecuteTrigger(TriggerWorkSpace *workSpace, const char *content, PAR
|
||||
|
||||
TriggerNode *ExecuteQueuePop(TriggerWorkSpace *workSpace);
|
||||
int ExecuteQueuePush(TriggerWorkSpace *workSpace, TriggerNode *trigger, u_int32_t index);
|
||||
int ExecuteQueueSize(TriggerWorkSpace *workSpace);
|
||||
int ExecuteQueueSize(const TriggerWorkSpace *workSpace);
|
||||
|
||||
u_int32_t AddTrigger(TriggerWorkSpace *workSpace, int type, const char *name, const char *condition);
|
||||
u_int32_t AddCommand(TriggerWorkSpace *workSpace, TriggerNode *trigger, const char *cmdName, const char *content);
|
||||
|
||||
@@ -55,6 +55,7 @@ static int InitNormalMemory(WorkSpace *workSpace, u_int32_t spaceSize)
|
||||
static ParamCacheNode *AllocParamCacheNode(WorkSpace *workSpace, u_int32_t size)
|
||||
{
|
||||
PARAM_CHECK(workSpace != NULL, return 0, "Invalid param");
|
||||
PARAM_CHECK(workSpace->area != NULL, return 0, "Invalid param area");
|
||||
PARAM_CHECK((workSpace->area->currOffset + size) < workSpace->area->dataSize, return 0,
|
||||
"Failed to allocate currOffset %d, dataSize %d", workSpace->area->currOffset, workSpace->area->dataSize);
|
||||
ParamCacheNode *cache = (ParamCacheNode *)(workSpace->area->data + workSpace->area->currOffset);
|
||||
@@ -134,6 +135,9 @@ const char *DetectParamChange(ParamWorkSpace *workSpace, ParamCache *cache,
|
||||
ParamEvaluatePtr evaluate, u_int32_t count, const char *parameters[][2])
|
||||
{
|
||||
pthread_mutex_lock(&cacheLock);
|
||||
if (cache == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
while (cache->cacheCount == 0) {
|
||||
int ret = CreateParamCache(cache, workSpace, evaluate);
|
||||
PARAM_CHECK(ret == 0, break, "Failed to create cache");
|
||||
|
||||
@@ -46,6 +46,7 @@ static int SelinuxAuditCallback(void *data,
|
||||
|
||||
int InitParamWorkSpace(ParamWorkSpace *workSpace, int onlyRead, const char *context)
|
||||
{
|
||||
PARAM_CHECK(workSpace != NULL, return PARAM_CODE_INVALID_NAME, "Invalid param");
|
||||
u_int32_t flags = atomic_load_explicit(&workSpace->flags, memory_order_relaxed);
|
||||
if ((flags & WORKSPACE_FLAGS_INIT) == WORKSPACE_FLAGS_INIT) {
|
||||
return 0;
|
||||
@@ -79,6 +80,7 @@ int InitParamWorkSpace(ParamWorkSpace *workSpace, int onlyRead, const char *cont
|
||||
|
||||
void CloseParamWorkSpace(ParamWorkSpace *workSpace)
|
||||
{
|
||||
PARAM_CHECK(workSpace != NULL, return, "Invalid work space");
|
||||
CloseWorkSpace(&workSpace->paramSpace);
|
||||
CloseWorkSpace(&workSpace->paramLabelSpace);
|
||||
atomic_store_explicit(&workSpace->flags, 0, memory_order_release);
|
||||
@@ -123,18 +125,16 @@ int WriteParamInfo(ParamWorkSpace *workSpace, SubStringInfo *info, int subStrNum
|
||||
|
||||
int AddParam(WorkSpace *workSpace, const char *name, const char *value)
|
||||
{
|
||||
PARAM_CHECK(workSpace != NULL && name != NULL && value != NULL,
|
||||
PARAM_CHECK(workSpace != NULL && workSpace->area != NULL && name != NULL && value != NULL,
|
||||
return PARAM_CODE_INVALID_PARAM, "Failed to check param");
|
||||
|
||||
TrieDataNode *node = AddTrieDataNode(workSpace, name, strlen(name));
|
||||
PARAM_CHECK(node != NULL, return PARAM_CODE_REACHED_MAX, "Failed to add node");
|
||||
DataEntry *entry = (DataEntry *)GetTrieNode(workSpace, &node->dataIndex);
|
||||
//PARAM_LOGI("AddParam entry %p", entry);
|
||||
if (entry == NULL) {
|
||||
u_int32_t offset = AddData(workSpace, name, strlen(name), value, strlen(value));
|
||||
PARAM_CHECK(offset > 0, return PARAM_CODE_REACHED_MAX, "Failed to allocate name %s", name);
|
||||
SaveIndex(&node->dataIndex, offset);
|
||||
//PARAM_LOGI("AddParam entry %p %u", entry, offset);
|
||||
}
|
||||
atomic_store_explicit(&workSpace->area->serial,
|
||||
atomic_load_explicit(&workSpace->area->serial, memory_order_relaxed) + 1, memory_order_release);
|
||||
@@ -161,7 +161,6 @@ int UpdateParam(WorkSpace *workSpace, u_int32_t *dataIndex, const char *name, co
|
||||
if (ret != 0) {
|
||||
PARAM_LOGE("Failed to update param value %s %s", name, value);
|
||||
}
|
||||
//PARAM_LOGI("UpdateParam entry %p", entry);
|
||||
atomic_store_explicit(&entry->serial, serial + 1, memory_order_release);
|
||||
futex_wake(&entry->serial, INT_MAX);
|
||||
atomic_store_explicit(&workSpace->area->serial,
|
||||
@@ -196,7 +195,6 @@ int WriteParamWithCheck(ParamWorkSpace *workSpace,
|
||||
PARAM_CHECK(ret == 0, return ret, "Illegal param name %s", name);
|
||||
TrieDataNode *info = FindTrieDataNode(&workSpace->paramSpace, name, strlen(name), 1);
|
||||
ret = CanWriteParam(workSpace, srcLabel, info, name, value);
|
||||
//PARAM_LOGI("WriteParamWithCheck info %p", info);
|
||||
PARAM_CHECK(ret == 0, return ret, "Permission to write param %s", name);
|
||||
return WriteParam(&workSpace->paramSpace, name, value);
|
||||
}
|
||||
@@ -209,7 +207,6 @@ int WriteParam(WorkSpace *workSpace, const char *name, const char *value)
|
||||
TrieDataNode *node = FindTrieDataNode(workSpace, name, strlen(name), 0);
|
||||
int ret = CheckParamValue(workSpace, node, name, value);
|
||||
PARAM_CHECK(ret == 0, return ret, "Invalid value %s %s", name, value);
|
||||
//PARAM_LOGI("WriteParamWithCheck node %p", node);
|
||||
if (node != NULL && node->dataIndex != 0) {
|
||||
return UpdateParam(workSpace, &node->dataIndex, name, value);
|
||||
}
|
||||
@@ -228,13 +225,12 @@ int ReadParamWithCheck(ParamWorkSpace *workSpace, const char *name, ParamHandle
|
||||
*handle = 0;
|
||||
// 取最长匹配
|
||||
TrieDataNode *paramInfo = FindTrieDataNode(&workSpace->paramSpace, name, strlen(name), 1);
|
||||
int ret = CanReadParam(workSpace, paramInfo == NULL ? 0 : paramInfo->labelIndex, name);
|
||||
int ret = CanReadParam(workSpace, (paramInfo == NULL) ? 0 : paramInfo->labelIndex, name);
|
||||
PARAM_CHECK(ret == 0, return ret, "Permission to read param %s", name);
|
||||
|
||||
// 查找结点
|
||||
TrieDataNode *node = FindTrieDataNode(&workSpace->paramSpace, name, strlen(name), 0);
|
||||
if (node != NULL && node->dataIndex != 0) {
|
||||
//PARAM_LOGI("ReadParamWithCheck trie %p dataIndex %u name %s", node, node->dataIndex, name);
|
||||
*handle = node->dataIndex;
|
||||
return 0;
|
||||
}
|
||||
@@ -295,8 +291,9 @@ int CheckControlParamPerms(ParamWorkSpace *workSpace,
|
||||
{
|
||||
PARAM_CHECK(srcLabel != NULL && name != NULL && value != NULL,
|
||||
return PARAM_CODE_INVALID_PARAM, "Invalid param");
|
||||
|
||||
char * ctrlName[] = {
|
||||
int ret = 0;
|
||||
int n = 0;
|
||||
const char *ctrlName[] = {
|
||||
"ctl.start", "ctl.stop", "ctl.restart"
|
||||
};
|
||||
size_t size1 = strlen("ctl.") + strlen(value);
|
||||
@@ -313,12 +310,12 @@ int CheckControlParamPerms(ParamWorkSpace *workSpace,
|
||||
// their value is the name of the service to apply that action to. Permissions for these
|
||||
// actions are based on the service, so we must create a fake name of ctl.<service> to
|
||||
// check permissions.
|
||||
int n = snprintf_s(legacyName, size, strlen("ctl.") + strlen(value) + 1, "ctl.%s", value);
|
||||
n = snprintf_s(legacyName, size, strlen("ctl.") + strlen(value) + 1, "ctl.%s", value);
|
||||
PARAM_CHECK(n > 0, free(legacyName); return PARAM_CODE_INVALID_PARAM, "Failed to snprintf value");
|
||||
legacyName[n] = '\0';
|
||||
|
||||
TrieDataNode *node = FindTrieDataNode(&workSpace->paramSpace, legacyName, strlen(legacyName), 1);
|
||||
int ret = CheckMacPerms(workSpace, srcLabel, legacyName, node == NULL ? 0 : node->labelIndex);
|
||||
ret = CheckMacPerms(workSpace, srcLabel, legacyName, (node == NULL) ? 0 : node->labelIndex);
|
||||
if (ret == 0) {
|
||||
free(legacyName);
|
||||
return 0;
|
||||
@@ -326,17 +323,20 @@ int CheckControlParamPerms(ParamWorkSpace *workSpace,
|
||||
break;
|
||||
}
|
||||
}
|
||||
int n = snprintf_s(legacyName, size, size, "%s$%s", name, value);
|
||||
n = snprintf_s(legacyName, size, size - 1, "%s$%s", name, value);
|
||||
PARAM_CHECK(n > 0, free(legacyName); return PARAM_CODE_INVALID_PARAM, "Failed to snprintf value");
|
||||
|
||||
TrieDataNode *node = FindTrieDataNode(&workSpace->paramSpace, name, strlen(name), 1);
|
||||
int ret = CheckMacPerms(workSpace, srcLabel, name, node == NULL ? 0 : node->labelIndex);
|
||||
ret = CheckMacPerms(workSpace, srcLabel, name, (node == NULL) ? 0 : node->labelIndex);
|
||||
free(legacyName);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int CheckParamName(const char *name, int info)
|
||||
{
|
||||
if (name == NULL) {
|
||||
return PARAM_CODE_INVALID_NAME;
|
||||
}
|
||||
size_t nameLen = strlen(name);
|
||||
if (nameLen >= PARAM_NAME_LEN_MAX) {
|
||||
return PARAM_CODE_INVALID_NAME;
|
||||
@@ -369,7 +369,10 @@ int CheckParamName(const char *name, int info)
|
||||
|
||||
int CheckParamValue(WorkSpace *workSpace, const TrieDataNode *node, const char *name, const char *value)
|
||||
{
|
||||
if (IS_READY_ONLY(name)) {
|
||||
if (name == NULL || value == NULL) {
|
||||
return PARAM_CODE_INVALID_VALUE;
|
||||
}
|
||||
if (strncmp((name), "ro.", strlen("ro.")) == 0) {
|
||||
if (node != NULL && node->dataIndex != 0) {
|
||||
PARAM_LOGE("Read-only param was already set %s", name);
|
||||
return PARAM_CODE_READ_ONLY_PROPERTY;
|
||||
@@ -397,7 +400,7 @@ int CheckMacPerms(ParamWorkSpace *workSpace,
|
||||
} else {
|
||||
ret = selinux_check_access(srcLabel, "u:object_r:default_prop:s0", "param_service", "set", &auditData);
|
||||
}
|
||||
return ret == 0 ? 0 : PARAM_CODE_PERMISSION_DENIED;
|
||||
return ((ret == 0) ? 0 : PARAM_CODE_PERMISSION_DENIED);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
@@ -409,11 +412,11 @@ int CanWriteParam(ParamWorkSpace *workSpace,
|
||||
PARAM_CHECK(workSpace != NULL && name != NULL && value != NULL && srcLabel != NULL,
|
||||
return PARAM_CODE_INVALID_PARAM, "Invalid param");
|
||||
|
||||
if (strncmp(name, "ctl.", strlen("ctl.")) == 0) { // 处理ctrl TODO
|
||||
if (strncmp(name, "ctl.", strlen("ctl.")) == 0) {
|
||||
return CheckControlParamPerms(workSpace, srcLabel, name, value);
|
||||
}
|
||||
|
||||
int ret = CheckMacPerms(workSpace, srcLabel, name, node == NULL ? 0 : node->labelIndex);
|
||||
int ret = CheckMacPerms(workSpace, srcLabel, name, (node == NULL) ? 0 : node->labelIndex);
|
||||
PARAM_CHECK(ret == 0, return ret, "SELinux permission check failed");
|
||||
return 0;
|
||||
}
|
||||
@@ -425,7 +428,11 @@ int CanReadParam(ParamWorkSpace *workSpace, u_int32_t labelIndex, const char *na
|
||||
#ifdef PARAM_SUPPORT_SELINUX
|
||||
ParamAuditData auditData;
|
||||
auditData.name = name;
|
||||
UserCred cr = {.pid = 0, .uid = 0, .gid = 0};
|
||||
UserCred cr = {
|
||||
.pid = 0,
|
||||
.uid = 0,
|
||||
.gid = 0
|
||||
};
|
||||
auditData.cr = &cr;
|
||||
|
||||
int ret = 0;
|
||||
@@ -433,9 +440,9 @@ int CanReadParam(ParamWorkSpace *workSpace, u_int32_t labelIndex, const char *na
|
||||
if (node != 0) { // 已经存在label
|
||||
ret = selinux_check_access(&workSpace->context, node->key, "param_service", "read", &auditData);
|
||||
} else {
|
||||
ret = selinux_check_access(&workSpace->context, "selinux_check_access", "file", "read", &auditData);
|
||||
ret = selinux_check_access(&workSpace->context, "selinux_check_access", "file", "read", &auditData);
|
||||
}
|
||||
return ret == 0 ? 0 : PARAM_CODE_PERMISSION_DENIED;
|
||||
return (ret == 0) ? 0 : PARAM_CODE_PERMISSION_DENIED;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
@@ -443,6 +450,9 @@ int CanReadParam(ParamWorkSpace *workSpace, u_int32_t labelIndex, const char *na
|
||||
|
||||
int GetSubStringInfo(const char *buff, u_int32_t buffLen, char delimiter, SubStringInfo *info, int subStrNumber)
|
||||
{
|
||||
if (buff == NULL || info == NULL) {
|
||||
return -1;
|
||||
}
|
||||
size_t i = 0;
|
||||
// 去掉开始的空格
|
||||
for (; i < strlen(buff); i++) {
|
||||
@@ -513,6 +523,10 @@ int BuildParamContent(char *content, u_int32_t contentSize, const char *name, co
|
||||
int ProcessParamTraversal(WorkSpace *workSpace, TrieNode *node, void *cookie)
|
||||
{
|
||||
ParamTraversalContext *context = (ParamTraversalContext *)cookie;
|
||||
if (context == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
TrieDataNode *current = (TrieDataNode *)node;
|
||||
if (current == NULL) {
|
||||
return 0;
|
||||
@@ -531,4 +545,4 @@ int TraversalParam(ParamWorkSpace *workSpace, TraversalParamPtr walkFunc, void *
|
||||
};
|
||||
return TraversalTrieDataNode(&workSpace->paramSpace,
|
||||
(TrieDataNode *)workSpace->paramSpace.rootNode, ProcessParamTraversal, &context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
@@ -85,7 +85,7 @@ int InitWorkSpace_(WorkSpace *workSpace, int mode, int prot, u_int32_t spaceSize
|
||||
PARAM_LOGD("InitWorkSpace %s ", workSpace->fileName);
|
||||
CheckAndCreateDir(workSpace->fileName);
|
||||
|
||||
int fd = open(workSpace->fileName, mode, 00777); //0444);
|
||||
int fd = open(workSpace->fileName, mode, S_IRWXU | S_IRWXG | S_IRWXO);
|
||||
PARAM_CHECK(fd >= 0, return PARAM_CODE_INVALID_NAME,
|
||||
"Open file %s fail error %s", workSpace->fileName, strerror(errno));
|
||||
|
||||
@@ -131,6 +131,9 @@ u_int32_t GetWorkSpaceSerial(WorkSpace *workSpace)
|
||||
|
||||
u_int32_t AllocateTrieNode(WorkSpace *workSpace, const char *key, u_int32_t keyLen)
|
||||
{
|
||||
if (workSpace == NULL || workSpace->area == NULL || key == NULL) {
|
||||
return 0;
|
||||
}
|
||||
u_int32_t len = keyLen + sizeof(TrieNode) + 1;
|
||||
len = (len + 0x03) & (~0x03);
|
||||
PARAM_CHECK((workSpace->area->currOffset + len) < workSpace->area->dataSize, return 0,
|
||||
@@ -138,7 +141,7 @@ u_int32_t AllocateTrieNode(WorkSpace *workSpace, const char *key, u_int32_t keyL
|
||||
TrieNode *node = (TrieNode*)(workSpace->area->data + workSpace->area->currOffset + len);
|
||||
|
||||
atomic_init(&node->serial, ATOMIC_VAR_INIT(keyLen << TRIE_SERIAL_KEY_LEN_OFFSET));
|
||||
int ret = memcpy_s(node->key, keyLen, key, keyLen);
|
||||
int ret = memcpy_s(node->key, keyLen + 1, key, keyLen);
|
||||
PARAM_CHECK(ret == 0, return 0, "Failed to copy key");
|
||||
node->key[keyLen] = '\0';
|
||||
node->left = 0;
|
||||
@@ -150,6 +153,9 @@ u_int32_t AllocateTrieNode(WorkSpace *workSpace, const char *key, u_int32_t keyL
|
||||
|
||||
u_int32_t AllocateTrieDataNode(WorkSpace *workSpace, const char *key, u_int32_t keyLen)
|
||||
{
|
||||
if (workSpace == NULL || workSpace->area == NULL || key == NULL) {
|
||||
return 0;
|
||||
}
|
||||
u_int32_t len = keyLen + sizeof(TrieDataNode) + 1;
|
||||
len = (len + 0x03) & (~0x03);
|
||||
PARAM_CHECK((workSpace->area->currOffset + len) < workSpace->area->dataSize, return 0,
|
||||
@@ -157,7 +163,7 @@ u_int32_t AllocateTrieDataNode(WorkSpace *workSpace, const char *key, u_int32_t
|
||||
TrieDataNode *node = (TrieDataNode*)(workSpace->area->data + workSpace->area->currOffset);
|
||||
|
||||
atomic_init(&node->serial, ATOMIC_VAR_INIT(keyLen << TRIE_SERIAL_KEY_LEN_OFFSET));
|
||||
int ret = memcpy_s(node->key, keyLen, key, keyLen);
|
||||
int ret = memcpy_s(node->key, keyLen + 1, key, keyLen);
|
||||
PARAM_CHECK(ret == 0, return 0, "Failed to copy key");
|
||||
node->key[keyLen] = '\0';
|
||||
node->left = 0;
|
||||
@@ -170,12 +176,12 @@ u_int32_t AllocateTrieDataNode(WorkSpace *workSpace, const char *key, u_int32_t
|
||||
return offset;
|
||||
}
|
||||
|
||||
TrieNode *GetTrieNode(WorkSpace *workSpace, NODE_INDEX *index)
|
||||
TrieNode *GetTrieNode(WorkSpace *workSpace, const unsigned int *index)
|
||||
{
|
||||
if (index == NULL) {
|
||||
if (index == NULL || workSpace == NULL || workSpace->area == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
u_int32_t offset = *index; // atomic_load_explicit(¤t->children, memory_order_relaxed);
|
||||
u_int32_t offset = *index;
|
||||
if (offset == 0 || offset > workSpace->area->dataSize) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -192,9 +198,8 @@ u_int32_t GetTrieNodeOffset(WorkSpace *workSpace, const TrieNode *current)
|
||||
return (((char *)current) - workSpace->area->data);
|
||||
}
|
||||
|
||||
void SaveIndex(NODE_INDEX *index, u_int32_t offset)
|
||||
void SaveIndex(unsigned int *index, u_int32_t offset)
|
||||
{
|
||||
// atomic_store_explicit(¤t->children, new_offset, memory_order_release);
|
||||
*index = offset;
|
||||
}
|
||||
|
||||
@@ -246,7 +251,7 @@ TrieDataNode *AddTrieDataNode(WorkSpace *workSpace, const char *key, u_int32_t k
|
||||
if (!subKeyLen) {
|
||||
return NULL;
|
||||
}
|
||||
u_int32_t offset = subKey == NULL ? strlen(key) : subKey - key;
|
||||
u_int32_t offset = ((subKey == NULL) ? strlen(key) : (subKey - key));
|
||||
|
||||
if (current->child != 0) { // 如果child存在,则检查是否匹配
|
||||
TrieDataNode *next = (TrieDataNode*)GetTrieNode(workSpace, ¤t->child);
|
||||
@@ -271,6 +276,8 @@ TrieDataNode *AddTrieDataNode(WorkSpace *workSpace, const char *key, u_int32_t k
|
||||
|
||||
TrieDataNode *AddToSubTrie(WorkSpace *workSpace, TrieDataNode *dataNode, const char *key, u_int32_t keyLen)
|
||||
{
|
||||
PARAM_CHECK(workSpace != NULL && dataNode != NULL, return NULL,
|
||||
"Invalid param");
|
||||
TrieDataNode *root = NULL;
|
||||
int ret = workSpace->compareTrieNode((TrieNode *)dataNode, key, keyLen);
|
||||
if (ret <= 0) {
|
||||
@@ -295,6 +302,7 @@ TrieDataNode *AddToSubTrie(WorkSpace *workSpace, TrieDataNode *dataNode, const c
|
||||
|
||||
TrieNode *AddTrieNode(WorkSpace *workSpace, TrieNode *root, const char *key, u_int32_t keyLen)
|
||||
{
|
||||
PARAM_CHECK(workSpace != NULL, return NULL, "Invalid work space");
|
||||
PARAM_CHECK(root != NULL, return NULL, "Invalid param %s", key);
|
||||
TrieNode *current = root;
|
||||
TrieNode *next = NULL;
|
||||
@@ -330,6 +338,7 @@ TrieNode *AddTrieNode(WorkSpace *workSpace, TrieNode *root, const char *key, u_i
|
||||
|
||||
TrieDataNode *FindTrieDataNode(WorkSpace *workSpace, const char *key, u_int32_t keyLen, int matchPrefix)
|
||||
{
|
||||
PARAM_CHECK(workSpace != NULL, return NULL, "Invalid param %s", key);
|
||||
PARAM_CHECK(workSpace->allocTrieNode != NULL, return NULL, "Invalid param %s", key);
|
||||
PARAM_CHECK(workSpace->compareTrieNode != NULL, return NULL, "Invalid param %s", key);
|
||||
|
||||
@@ -344,7 +353,7 @@ TrieDataNode *FindTrieDataNode(WorkSpace *workSpace, const char *key, u_int32_t
|
||||
if (!subKeyLen) {
|
||||
return matchPrefix ? matchNode : NULL;
|
||||
}
|
||||
u_int32_t offset = subKey == NULL ? strlen(key) : subKey - key;
|
||||
u_int32_t offset = ((subKey == NULL) ? strlen(key) : (subKey - key));
|
||||
|
||||
if (current->child != 0) { // 如果child存在,则检查是否匹配
|
||||
TrieDataNode *next = (TrieDataNode*)GetTrieNode(workSpace, ¤t->child);
|
||||
@@ -370,6 +379,8 @@ TrieDataNode *FindTrieDataNode(WorkSpace *workSpace, const char *key, u_int32_t
|
||||
|
||||
TrieDataNode *FindSubTrie(WorkSpace *workSpace, TrieDataNode *dataNode, const char *key, u_int32_t keyLen)
|
||||
{
|
||||
PARAM_CHECK(workSpace != NULL, return NULL, "Invalid param %s", key);
|
||||
PARAM_CHECK(dataNode != NULL, return NULL, "Invalid param %s", key);
|
||||
TrieDataNode *root = NULL;
|
||||
int ret = workSpace->compareTrieNode((TrieNode*)dataNode, key, keyLen);
|
||||
if (ret <= 0) {
|
||||
@@ -388,6 +399,7 @@ TrieDataNode *FindSubTrie(WorkSpace *workSpace, TrieDataNode *dataNode, const ch
|
||||
|
||||
TrieNode *FindTrieNode(WorkSpace *workSpace, TrieNode *root, const char *key, u_int32_t keyLen)
|
||||
{
|
||||
PARAM_CHECK(workSpace != NULL, return NULL, "Invalid param %s", key);
|
||||
PARAM_CHECK(root != NULL, return NULL, "Invalid param %s", key);
|
||||
TrieNode *current = root;
|
||||
TrieNode *next = NULL;
|
||||
@@ -453,7 +465,7 @@ int TraversalTrieNode(WorkSpace *workSpace, TrieNode *root, TraversalTrieNodePtr
|
||||
|
||||
u_int32_t AddData(WorkSpace *workSpace, const char *key, u_int32_t keyLen, const char *value, u_int32_t valueLen)
|
||||
{
|
||||
PARAM_CHECK(workSpace != NULL, return 0, "Invalid param");
|
||||
PARAM_CHECK(workSpace != NULL && workSpace->area != NULL, return 0, "Invalid param");
|
||||
PARAM_CHECK(key != NULL && value != NULL, return 0, "Invalid param");
|
||||
u_int32_t realLen = sizeof(DataEntry) + 1 + 1;
|
||||
if (valueLen > PARAM_VALUE_LEN_MAX) {
|
||||
@@ -462,7 +474,6 @@ u_int32_t AddData(WorkSpace *workSpace, const char *key, u_int32_t keyLen, const
|
||||
realLen += keyLen + PARAM_VALUE_LEN_MAX;
|
||||
}
|
||||
realLen = (realLen + 0x03) & (~0x03);
|
||||
//PARAM_LOGI("AddData realLen %u %u %u", realLen, keyLen, valueLen);
|
||||
PARAM_CHECK((workSpace->area->currOffset + realLen) < workSpace->area->dataSize, return 0,
|
||||
"Failed to allocate currOffset %d, dataSize %d", workSpace->area->currOffset, workSpace->area->dataSize);
|
||||
|
||||
@@ -470,15 +481,14 @@ u_int32_t AddData(WorkSpace *workSpace, const char *key, u_int32_t keyLen, const
|
||||
u_int32_t dataLength = keyLen << TRIE_SERIAL_KEY_LEN_OFFSET | valueLen << TRIE_SERIAL_DATA_LEN_OFFSET;
|
||||
atomic_init(&node->serial, ATOMIC_VAR_INIT(0));
|
||||
atomic_init(&node->dataLength, ATOMIC_VAR_INIT(dataLength));
|
||||
int ret = memcpy_s(node->data, keyLen, key, keyLen);
|
||||
int ret = memcpy_s(node->data, keyLen + 1, key, keyLen);
|
||||
PARAM_CHECK(ret == 0, return 0, "Failed to copy key");
|
||||
ret = memcpy_s(node->data + keyLen + 1, valueLen, value, valueLen);
|
||||
ret = memcpy_s(node->data + keyLen + 1, valueLen + 1, value, valueLen);
|
||||
PARAM_CHECK(ret == 0, return 0, "Failed to copy key");
|
||||
node->data[keyLen] = '=';
|
||||
node->data[keyLen + 1 + valueLen] = '\0';
|
||||
u_int32_t offset = workSpace->area->currOffset;
|
||||
workSpace->area->currOffset += realLen;
|
||||
//PARAM_LOGI("AddData node %p %u %d", node, offset, gettid());
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
||||
@@ -59,8 +59,6 @@ static int ProcessParamTraversal(WorkSpace *workSpace, TrieNode *node, void *coo
|
||||
}
|
||||
ret = GetDataValue(entry, persistContext->buffer + MAX_BUFF, MAX_BUFF);
|
||||
if (ret == 0) { // 只支持新建
|
||||
//PARAM_LOGI("Insert new persist param from normal param %s %s",
|
||||
// persistContext->buffer, persistContext->buffer + MAX_BUFF);
|
||||
ret = AddParam(persistContext->persistWorkSpace, persistContext->buffer, persistContext->buffer + MAX_BUFF);
|
||||
}
|
||||
PARAM_CHECK(ret == 0, return ret, "Failed to add persist param");
|
||||
@@ -82,8 +80,6 @@ static int ProcessPersistPropertTraversal(WorkSpace *workSpace, TrieNode *node,
|
||||
PARAM_CHECK(ret == 0, return ret, "GetDataName failed");
|
||||
ret = GetDataValue(entry, persistContext->buffer + MAX_BUFF, MAX_BUFF);
|
||||
if (ret == 0) {
|
||||
//PARAM_LOGI("update normal param %s %s from persist param %u",
|
||||
// persistContext->buffer, persistContext->buffer + MAX_BUFF, current->dataIndex);
|
||||
ret = WriteParam(persistContext->workSpace, persistContext->buffer, persistContext->buffer + MAX_BUFF);
|
||||
}
|
||||
PARAM_CHECK(ret == 0, return ret, "Failed to add persist param");
|
||||
@@ -106,6 +102,7 @@ int InitPersistParamWorkSpace(const char *context)
|
||||
|
||||
int RefreshPersistParams(ParamWorkSpace *workSpace, const char *context)
|
||||
{
|
||||
PARAM_CHECK(workSpace != NULL, return -1, "Invalid param workspace");
|
||||
int ret = InitPersistParamWorkSpace(context);
|
||||
PARAM_CHECK(ret == 0, return ret, "Failed to init persist param");
|
||||
u_int32_t flags = atomic_load_explicit(&g_persistWorkSpace.flags, memory_order_relaxed);
|
||||
|
||||
@@ -20,11 +20,11 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "sys_param.h"
|
||||
#include "init_param.h"
|
||||
#include "init_utils.h"
|
||||
#include "param_manager.h"
|
||||
#include "param_request.h"
|
||||
#include "init_param.h"
|
||||
|
||||
#include "sys_param.h"
|
||||
#include "uv.h"
|
||||
|
||||
#define BUFFER_SIZE 256
|
||||
@@ -49,9 +49,12 @@ int LoadDefaultParams(const char *fileName)
|
||||
PARAM_CHECK(fp != NULL, return -1, "Open file %s fail", fileName);
|
||||
char buff[BUFFER_SIZE];
|
||||
SubStringInfo *info = malloc(sizeof(SubStringInfo) * (SUBSTR_INFO_LABEL + 1));
|
||||
PARAM_CHECK(info != NULL, return -1, "malloc failed");
|
||||
PARAM_CHECK(info != NULL,
|
||||
fclose(fp);
|
||||
fp = NULL;
|
||||
return -1, "malloc failed");
|
||||
|
||||
while(fgets(buff, BUFFER_SIZE, fp) != NULL) {
|
||||
while (fgets(buff, BUFFER_SIZE, fp) != NULL) {
|
||||
int subStrNumber = GetSubStringInfo(buff, strlen(buff), '=', info, SUBSTR_INFO_LABEL + 1);
|
||||
if (subStrNumber <= SUBSTR_INFO_LABEL) {
|
||||
continue;
|
||||
@@ -86,10 +89,13 @@ int LoadParamInfos(const char *fileName)
|
||||
FILE *fp = fopen(fileName, "r");
|
||||
PARAM_CHECK(fp != NULL, return -1, "Open file %s fail", fileName);
|
||||
SubStringInfo *info = malloc(sizeof(SubStringInfo) * SUBSTR_INFO_MAX);
|
||||
PARAM_CHECK(info != NULL, return -1, "Load parameter malloc failed.");
|
||||
PARAM_CHECK(info != NULL,
|
||||
fclose(fp);
|
||||
fp = NULL;
|
||||
return -1, "Load parameter malloc failed.");
|
||||
char buff[BUFFER_SIZE];
|
||||
int infoCount = 0;
|
||||
while(fgets(buff, BUFFER_SIZE, fp) != NULL) {
|
||||
while (fgets(buff, BUFFER_SIZE, fp) != NULL) {
|
||||
int subStrNumber = GetSubStringInfo(buff, strlen(buff), ' ', info, SUBSTR_INFO_MAX);
|
||||
if (subStrNumber <= 0) {
|
||||
continue;
|
||||
@@ -104,12 +110,13 @@ int LoadParamInfos(const char *fileName)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ProcessParamSet(RequestMsg *msg)
|
||||
static int ProcessParamSet(const RequestMsg *msg)
|
||||
{
|
||||
PARAM_CHECK(msg != NULL, return PARAM_CODE_INVALID_PARAM, "Failed to check param");
|
||||
|
||||
SubStringInfo info[3];
|
||||
int ret = GetSubStringInfo(msg->content, msg->contentSize, '=', info, sizeof(info)/sizeof(info[0]));
|
||||
int ret = GetSubStringInfo(msg->content, msg->contentSize, '=', info,
|
||||
ARRAY_LENGTH(info));
|
||||
PARAM_CHECK(ret >= 2, return ret, "Failed to get name from content %s", msg->content);
|
||||
|
||||
PARAM_LOGD("ProcessParamSet name %s value: %s", info[0].value, info[1].value);
|
||||
@@ -130,7 +137,8 @@ static void OnClose(uv_handle_t *handle)
|
||||
static void OnReceiveAlloc(uv_handle_t *handle, size_t suggestedSize, uv_buf_t* buf)
|
||||
{
|
||||
// 这里需要按实际消息的大小申请内存,取最大消息的长度
|
||||
buf->len = sizeof(RequestMsg) + BUFFER_SIZE * 2;
|
||||
unsigned int tmp = 2;
|
||||
buf->len = sizeof(RequestMsg) + BUFFER_SIZE * tmp;
|
||||
buf->base = (char *)malloc(buf->len);
|
||||
}
|
||||
|
||||
@@ -146,6 +154,7 @@ static void SendResponse(uv_stream_t *handle, RequestType type, int result, cons
|
||||
{
|
||||
int ret = 0;
|
||||
// 申请整块内存,用于回复数据和写请求
|
||||
PARAM_CHECK(size >= 0, return, "Invalid content size %d", size);
|
||||
ResponseNode *response = (ResponseNode *)malloc(sizeof(ResponseNode) + size);
|
||||
PARAM_CHECK(response != NULL, return, "Failed to alloc memory for response");
|
||||
response->msg.type = type;
|
||||
@@ -153,11 +162,17 @@ static void SendResponse(uv_stream_t *handle, RequestType type, int result, cons
|
||||
response->msg.result = result;
|
||||
if (content != NULL && size != 0) {
|
||||
ret = memcpy_s(response->msg.content, size, content, size);
|
||||
PARAM_CHECK(ret == 0, return, "Failed to copy content");
|
||||
PARAM_CHECK(ret == 0,
|
||||
free(response);
|
||||
response = NULL;
|
||||
return, "Failed to copy content");
|
||||
}
|
||||
uv_buf_t buf = uv_buf_init((char *)&response->msg, sizeof(response->msg) + size);
|
||||
ret = uv_write2(&response->writer, handle, &buf, 1, handle, OnWriteResponse);
|
||||
PARAM_CHECK(ret >= 0, return, "Failed to uv_write2 ret %s", uv_strerror(ret));
|
||||
PARAM_CHECK(ret >= 0,
|
||||
free(response);
|
||||
response = NULL;
|
||||
return, "Failed to uv_write2 ret %s", uv_strerror(ret));
|
||||
}
|
||||
|
||||
static void OnReceiveRequest(uv_stream_t *handle, ssize_t nread, uv_buf_t *buf)
|
||||
@@ -166,6 +181,7 @@ static void OnReceiveRequest(uv_stream_t *handle, ssize_t nread, uv_buf_t *buf)
|
||||
uv_close((uv_handle_t*)handle, OnClose);
|
||||
if (buf != NULL && buf->base != NULL) {
|
||||
free(buf->base);
|
||||
buf->base = NULL;
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -276,4 +292,4 @@ int SystemTraversalParam(void (*traversalParameter)(ParamHandle handle, void* co
|
||||
{
|
||||
PARAM_CHECK(traversalParameter != NULL, return -1, "The param is null");
|
||||
return TraversalParam(&g_paramWorkSpace, traversalParameter, cookie);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,13 +19,14 @@
|
||||
#include "init_param.h"
|
||||
|
||||
#define LABEL "Trigger"
|
||||
// 申请整块能存作为计算的节点
|
||||
// 申请整块内存作为计算的节点
|
||||
int CalculatorInit(LogicCalculator *calculator, int dataNumber, int dataUnit, int needCondition)
|
||||
{
|
||||
PARAM_CHECK(calculator != NULL, return -1, "Invalid param");
|
||||
int dataSize = dataUnit * dataNumber;
|
||||
int multiple = 5;
|
||||
if (needCondition) {
|
||||
dataSize += 5 * SUPPORT_DATA_BUFFER_MAX;
|
||||
dataSize += multiple * SUPPORT_DATA_BUFFER_MAX;
|
||||
}
|
||||
calculator->data = (char *)malloc(dataSize);
|
||||
PARAM_CHECK(calculator->data != NULL, return -1, "Failed to malloc for calculator");
|
||||
@@ -113,7 +114,8 @@ static int CalculatorLength(const LogicCalculator *calculator)
|
||||
|
||||
static int PrefixAdd(char *prefix, u_int32_t *prefixIndex, u_int32_t prefixLen, char op)
|
||||
{
|
||||
if ((*prefixIndex + 3) >= prefixLen) {
|
||||
u_int32_t offset = 3;
|
||||
if ((*prefixIndex + offset) >= prefixLen) {
|
||||
return -1;
|
||||
}
|
||||
prefix[(*prefixIndex)++] = ' ';
|
||||
@@ -127,7 +129,7 @@ static int HandleOperationOr(LogicCalculator *calculator, char *prefix, u_int32_
|
||||
int ret = 0;
|
||||
char e;
|
||||
prefix[(*prefixIndex)++] = ' ';
|
||||
if(CalculatorLength(calculator) == 0) {
|
||||
if (CalculatorLength(calculator) == 0) {
|
||||
CalculatorPushChar(calculator, '|');
|
||||
} else {
|
||||
do {
|
||||
@@ -152,7 +154,8 @@ static int ComputeSubCondition(LogicCalculator *calculator, LogicData *data, con
|
||||
// 解析条件
|
||||
char *subStr = strstr(condition + data->startIndex, "=");
|
||||
if (subStr != NULL && ((u_int32_t)(subStr - condition) > data->endIndex)) {
|
||||
if (strncmp(condition + data->startIndex, calculator->triggerContent, strlen(calculator->triggerContent)) == 0) {
|
||||
if (strncmp(condition + data->startIndex, calculator->triggerContent,
|
||||
strlen(calculator->triggerContent)) == 0) {
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
@@ -174,7 +177,7 @@ static int ComputeSubCondition(LogicCalculator *calculator, LogicData *data, con
|
||||
u_int32_t len = SUPPORT_DATA_BUFFER_MAX;
|
||||
ret = SystemReadParam(calculator->conditionName, calculator->readContent, &len);
|
||||
if (ret == 0 && (strcmp(calculator->conditionContent, "*") == 0 ||
|
||||
strcmp(calculator->conditionContent, calculator->readContent) == 0)) {
|
||||
strcmp(calculator->conditionContent, calculator->readContent) == 0)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -186,6 +189,7 @@ int GetValueFromContent(const char *content, u_int32_t contentSize, u_int32_t st
|
||||
{
|
||||
u_int32_t contentIndex = start;
|
||||
u_int32_t currIndex = 0;
|
||||
PARAM_CHECK(content != NULL && value != NULL, return -1, "Invalid arguments");
|
||||
while (contentIndex < contentSize && currIndex < valueSize) {
|
||||
if (content[contentIndex] == '=') {
|
||||
value[currIndex++] = '\0';
|
||||
@@ -206,6 +210,7 @@ int ComputeCondition(LogicCalculator *calculator, const char *condition)
|
||||
u_int32_t start = 0;
|
||||
int noneOper = 1;
|
||||
CalculatorClear(calculator);
|
||||
PARAM_CHECK(condition != NULL, return -1, "Invalid condition");
|
||||
LogicData data1 = {};
|
||||
LogicData data2 = {};
|
||||
while (currIndex < strlen(condition)) {
|
||||
@@ -258,8 +263,11 @@ int ConvertInfixToPrefix(const char *condition, char *prefix, u_int32_t prefixLe
|
||||
int ret = 0;
|
||||
u_int32_t curr = 0;
|
||||
u_int32_t prefixIndex = 0;
|
||||
int dataNumber = 100;
|
||||
|
||||
PARAM_CHECK(condition != NULL, return -1, "Invalid condition");
|
||||
LogicCalculator calculator;
|
||||
CalculatorInit(&calculator, 100, 1, 0);
|
||||
CalculatorInit(&calculator, dataNumber, 1, 0);
|
||||
|
||||
while (curr < strlen(condition)) {
|
||||
if (condition[curr] == ')') {
|
||||
@@ -302,9 +310,10 @@ int ConvertInfixToPrefix(const char *condition, char *prefix, u_int32_t prefixLe
|
||||
|
||||
char *GetMatchedSubCondition(const char *condition, const char *input, int length)
|
||||
{
|
||||
PARAM_CHECK(condition != NULL && input != NULL, return NULL, "Invalid arguments");
|
||||
const char *p = condition;
|
||||
for(;(p = strchr(p, *input)) != 0; p++) {
|
||||
if(strncmp(p, input, length) == 0) {
|
||||
for (; (p = strchr(p, *input)) != 0; p++) {
|
||||
if (strncmp(p, input, length) == 0) {
|
||||
return (char*)p;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
@@ -50,7 +50,7 @@ int InitTriggerWorkSpace(TriggerWorkSpace *workSpace)
|
||||
return 0;
|
||||
}
|
||||
CheckAndCreateDir(TRIGGER_PATH);
|
||||
int fd = open(TRIGGER_PATH, O_CREAT | O_RDWR | O_TRUNC | O_CLOEXEC, 0444);
|
||||
int fd = open(TRIGGER_PATH, O_CREAT | O_RDWR | O_TRUNC | O_CLOEXEC, S_IRUSR | S_IRGRP | S_IROTH);
|
||||
PARAM_CHECK(fd >= 0, return -1, "Open file fail error %s", strerror(errno));
|
||||
lseek(fd, TRIGGER_AREA_SPACE, SEEK_SET);
|
||||
write(fd, "", 1);
|
||||
@@ -79,12 +79,13 @@ int InitTriggerWorkSpace(TriggerWorkSpace *workSpace)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static CommandNode *GetCmdByIndex(TriggerWorkSpace *workSpace, TriggerNode *trigger, u_int32_t index)
|
||||
static CommandNode *GetCmdByIndex(const TriggerWorkSpace *workSpace, const TriggerNode *trigger, u_int32_t index)
|
||||
{
|
||||
if (index == 0 || index == (u_int32_t)-1) {
|
||||
return NULL;
|
||||
}
|
||||
u_int32_t size = sizeof(CommandNode) + 2;
|
||||
u_int32_t offset = 2;
|
||||
u_int32_t size = sizeof(CommandNode) + offset;
|
||||
PARAM_CHECK((index + size) < workSpace->area->dataSize,
|
||||
return NULL, "Invalid index for cmd %u", index);
|
||||
return (CommandNode *)(workSpace->area->data + index);
|
||||
@@ -93,8 +94,9 @@ static CommandNode *GetCmdByIndex(TriggerWorkSpace *workSpace, TriggerNode *trig
|
||||
u_int32_t AddCommand(TriggerWorkSpace *workSpace, TriggerNode *trigger, const char *cmdName, const char *content)
|
||||
{
|
||||
PARAM_CHECK(workSpace != NULL && trigger != NULL, return 0, "list is null");
|
||||
PARAM_CHECK(workSpace->area != NULL, return 0, "Invalid trigger workspace");
|
||||
u_int32_t size = sizeof(CommandNode) + strlen(cmdName) + 1;
|
||||
size += (content == NULL) ? 1 : strlen(content) + 1;
|
||||
size += ((content == NULL) ? 1 : (strlen(content) + 1));
|
||||
size = (size + 0x03) & (~0x03);
|
||||
PARAM_CHECK((workSpace->area->currOffset + size) < workSpace->area->dataSize,
|
||||
return 0, "Not enough memory for cmd %u %u", size, workSpace->area->currOffset);
|
||||
@@ -144,11 +146,12 @@ static TriggerNode *GetTriggerByIndex(TriggerWorkSpace *workSpace, u_int32_t ind
|
||||
u_int32_t AddTrigger(TriggerWorkSpace *workSpace, int type, const char *name, const char *condition)
|
||||
{
|
||||
PARAM_CHECK(workSpace != NULL && name != NULL, return 0, "list is null");
|
||||
PARAM_CHECK(workSpace->area != NULL, return 0, "Invalid trigger workspace");
|
||||
const char *tmpCond = condition;
|
||||
if (type == TRIGGER_BOOT && condition == NULL) {
|
||||
tmpCond = name;
|
||||
}
|
||||
u_int32_t conditionSize = (tmpCond == NULL) ? 1 : strlen(tmpCond) + 1 + CONDITION_EXTEND_LEN;
|
||||
u_int32_t conditionSize = ((tmpCond == NULL) ? 1 : (strlen(tmpCond) + 1 + CONDITION_EXTEND_LEN));
|
||||
conditionSize = (conditionSize + 0x03) & (~0x03);
|
||||
PARAM_CHECK((workSpace->area->currOffset + sizeof(TriggerNode) + conditionSize) < workSpace->area->dataSize,
|
||||
return -1, "Not enough memory for cmd");
|
||||
@@ -205,7 +208,7 @@ static int GetTriggerIndex(const char *type)
|
||||
return TRIGGER_UNKNOW;
|
||||
}
|
||||
|
||||
int ParseTrigger(TriggerWorkSpace *workSpace, cJSON *triggerItem)
|
||||
int ParseTrigger(TriggerWorkSpace *workSpace, const cJSON *triggerItem)
|
||||
{
|
||||
PARAM_CHECK(triggerItem != NULL, return -1, "Invalid file");
|
||||
PARAM_CHECK(workSpace != NULL, return -1, "Failed to create trigger list");
|
||||
@@ -252,7 +255,6 @@ int ParseTrigger(TriggerWorkSpace *workSpace, cJSON *triggerItem)
|
||||
} else {
|
||||
offset = AddCommand(workSpace, trigger, matchCmd, cmdLineStr + matchLen);
|
||||
}
|
||||
//PARAM_LOGE("AddCommand %u %s %u", offset, cmdLineStr, workSpace->area->currOffset);
|
||||
PARAM_CHECK(offset > 0, continue, "Failed to add command %s", cmdLineStr);
|
||||
}
|
||||
return 0;
|
||||
@@ -282,6 +284,7 @@ int ExecuteQueuePush(TriggerWorkSpace *workSpace, TriggerNode *trigger, u_int32_
|
||||
|
||||
TriggerNode *ExecuteQueuePop(TriggerWorkSpace *workSpace)
|
||||
{
|
||||
PARAM_CHECK(workSpace != NULL, return NULL, "Invalid param");
|
||||
if (workSpace->executeQueue.endIndex <= workSpace->executeQueue.startIndex) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -294,14 +297,14 @@ TriggerNode *ExecuteQueuePop(TriggerWorkSpace *workSpace)
|
||||
return GetTriggerByIndex(workSpace, triggerIndex);
|
||||
}
|
||||
|
||||
int ExecuteQueueSize(TriggerWorkSpace *workSpace)
|
||||
int ExecuteQueueSize(const TriggerWorkSpace *workSpace)
|
||||
{
|
||||
PARAM_CHECK(workSpace != NULL, return 0, "Invalid param");
|
||||
return workSpace->executeQueue.endIndex - workSpace->executeQueue.startIndex;
|
||||
}
|
||||
|
||||
static int CheckBootTriggerMatch(LogicCalculator *calculator,
|
||||
TriggerNode *trigger, const char *content, u_int32_t contentSize)
|
||||
static int CheckBootTriggerMatch(const LogicCalculator *calculator,
|
||||
const TriggerNode *trigger, const char *content, u_int32_t contentSize)
|
||||
{
|
||||
if (strncmp(trigger->name, (char *)content, contentSize) == 0) {
|
||||
return 1;
|
||||
@@ -310,7 +313,7 @@ static int CheckBootTriggerMatch(LogicCalculator *calculator,
|
||||
}
|
||||
|
||||
static int CheckParamTriggerMatch(LogicCalculator *calculator,
|
||||
TriggerNode *trigger, const char *content, u_int32_t contentSize)
|
||||
const TriggerNode *trigger, const char *content, u_int32_t contentSize)
|
||||
{
|
||||
if (calculator->inputName != NULL) { // 存在input数据时,先过滤非input的
|
||||
if (GetMatchedSubCondition(trigger->condition, content, strlen(calculator->inputName) + 1) == NULL) {
|
||||
@@ -321,7 +324,7 @@ static int CheckParamTriggerMatch(LogicCalculator *calculator,
|
||||
}
|
||||
|
||||
static int CheckOtherTriggerMatch(LogicCalculator *calculator,
|
||||
TriggerNode *trigger, const char *content, u_int32_t contentSize)
|
||||
const TriggerNode *trigger, const char *content, u_int32_t contentSize)
|
||||
{
|
||||
return ComputeCondition(calculator, trigger->condition);
|
||||
}
|
||||
@@ -368,7 +371,8 @@ int CheckParamTrigger(TriggerWorkSpace *workSpace,
|
||||
PARAM_CHECK(workSpace != NULL && content != NULL && triggerExecuter != NULL,
|
||||
return -1, "Failed arg for param trigger");
|
||||
LogicCalculator calculator = {};
|
||||
CalculatorInit(&calculator, 100, sizeof(LogicData), 1);
|
||||
int dataNumber = 100;
|
||||
CalculatorInit(&calculator, dataNumber, sizeof(LogicData), 1);
|
||||
|
||||
// 先解析content
|
||||
int ret = GetValueFromContent(content, contentSize, 0, calculator.inputName, SUPPORT_DATA_BUFFER_MAX);
|
||||
@@ -388,7 +392,8 @@ int CheckAndExecuteTrigger(TriggerWorkSpace *workSpace, const char *content, PAR
|
||||
PARAM_CHECK(workSpace != NULL && content != NULL && triggerExecuter != NULL,
|
||||
return -1, "Failed arg for param trigger");
|
||||
LogicCalculator calculator = {};
|
||||
CalculatorInit(&calculator, 100, sizeof(LogicData), 1);
|
||||
int dataNumber = 100;
|
||||
CalculatorInit(&calculator, dataNumber, sizeof(LogicData), 1);
|
||||
|
||||
int ret = memcpy_s(calculator.triggerContent, sizeof(calculator.triggerContent), content, strlen(content));
|
||||
PARAM_CHECK(ret == 0, CalculatorFree(&calculator); return -1, "Failed to memcpy");
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
static TriggerWorkSpace g_triggerWorkSpace = {};
|
||||
|
||||
static int DoCmdExecute(TriggerNode *trigger, const char *cmdName, const char *command)
|
||||
static int DoCmdExecute(const TriggerNode *trigger, const char *cmdName, const char *command)
|
||||
{
|
||||
PARAM_CHECK(trigger != NULL && cmdName != NULL && command != NULL, return -1, "Invalid param");
|
||||
PARAM_LOGD("DoCmdExecute trigger %s cmd %s %s", trigger->name, cmdName, command);
|
||||
@@ -44,7 +44,6 @@ static int DoCmdExecute(TriggerNode *trigger, const char *cmdName, const char *c
|
||||
|
||||
static int DoTiggerCheckResult(TriggerNode *trigger, u_int32_t triggerIndex)
|
||||
{
|
||||
// 已经在队列中了,则不执行 TODO
|
||||
if (TRIGGER_NODE_IN_QUEUE(trigger)) {
|
||||
PARAM_LOGI("DoTiggerExecute trigger %s has been waiting execute", trigger->name);
|
||||
return 0;
|
||||
@@ -152,7 +151,8 @@ void PostParamTrigger(const char *name, const char *value)
|
||||
{
|
||||
PARAM_CHECK(name != NULL && value != NULL, return, "Invalid param");
|
||||
PARAM_LOGD("PostParamTrigger %s ", name);
|
||||
int contentLen = strlen(name) + strlen(value) + 2;
|
||||
int offset = 2;
|
||||
int contentLen = strlen(name) + strlen(value) + offset;
|
||||
TriggerDataEvent *event = (TriggerDataEvent *)malloc(sizeof(TriggerDataEvent) + contentLen);
|
||||
PARAM_CHECK(event != NULL, return, "Failed to alloc memory");
|
||||
event->type = EVENT_PROPERTY;
|
||||
@@ -172,13 +172,13 @@ void PostTrigger(EventType type, const char *content, u_int32_t contentLen)
|
||||
event->type = type;
|
||||
event->request.data = (char*)event + sizeof(uv_work_t);
|
||||
event->contentSize = contentLen;
|
||||
PARAM_CHECK(memcpy_s(event->content, contentLen, content, contentLen) == 0, return, "Failed to copy content");
|
||||
PARAM_CHECK(memcpy_s(event->content, contentLen + 1, content, contentLen) == 0, return, "Failed to copy content");
|
||||
event->content[contentLen] = '\0';
|
||||
SendTriggerEvent(event);
|
||||
PARAM_LOGD("PostTrigger %d success", type);
|
||||
}
|
||||
|
||||
int ParseTriggerConfig(cJSON *fileRoot)
|
||||
int ParseTriggerConfig(const cJSON *fileRoot)
|
||||
{
|
||||
PARAM_CHECK(fileRoot != NULL, return -1, "Invalid file");
|
||||
int ret = InitTriggerWorkSpace(&g_triggerWorkSpace);
|
||||
|
||||
@@ -112,7 +112,7 @@ static int GetServiceStringCaps(const cJSON* filedJ, Service* curServ)
|
||||
return SERVICE_FAILURE;
|
||||
}
|
||||
}
|
||||
int ret = i == curServ->servPerm.capsCnt ? SERVICE_SUCCESS : SERVICE_FAILURE;
|
||||
int ret = ((i == curServ->servPerm.capsCnt) ? SERVICE_SUCCESS : SERVICE_FAILURE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
+76
-78
@@ -122,103 +122,101 @@ inline int GetParamValue(const char *symValue, char *paramValue, unsigned int pa
|
||||
}
|
||||
#endif
|
||||
|
||||
struct CmdArgs* GetCmd(const char *cmdContent, const char *delim, int argsCount)
|
||||
static struct CmdArgs *CopyCmd(struct CmdArgs *ctx, const char *cmd, size_t allocSize)
|
||||
{
|
||||
if (cmd == NULL) {
|
||||
FreeCmd(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctx->argv[ctx->argc] = calloc(sizeof(char), allocSize);
|
||||
INIT_CHECK(ctx->argv[ctx->argc] != NULL, FreeCmd(ctx);
|
||||
return NULL);
|
||||
INIT_CHECK(GetParamValue(cmd, ctx->argv[ctx->argc], allocSize) == 0, FreeCmd(ctx);
|
||||
return NULL);
|
||||
ctx->argc += 1;
|
||||
ctx->argv[ctx->argc] = NULL;
|
||||
return ctx;
|
||||
}
|
||||
|
||||
#define SKIP_SPACES(p) \
|
||||
do { \
|
||||
while (isspace(*(p))) { \
|
||||
(p)++; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
struct CmdArgs *GetCmd(const char *cmdContent, const char *delim, int argsCount)
|
||||
{
|
||||
INIT_CHECK_RETURN_VALUE(cmdContent != NULL, NULL);
|
||||
struct CmdArgs *ctx = (struct CmdArgs *)malloc(sizeof(struct CmdArgs));
|
||||
INIT_CHECK_RETURN_VALUE(ctx != NULL, NULL);
|
||||
|
||||
if (argsCount > SPACES_CNT_IN_CMD_MAX) {
|
||||
INIT_LOGW("Too much arguments for command, max number is %d", SPACES_CNT_IN_CMD_MAX);
|
||||
argsCount = SPACES_CNT_IN_CMD_MAX;
|
||||
}
|
||||
ctx->argv = (char**)malloc(sizeof(char*) * (size_t)argsCount + 1);
|
||||
INIT_CHECK(ctx->argv != NULL, FreeCmd(&ctx); return NULL);
|
||||
ctx->argv = (char**)malloc(sizeof(char*) * (size_t)(argsCount + 1));
|
||||
INIT_CHECK(ctx->argv != NULL, FreeCmd(ctx);
|
||||
return NULL);
|
||||
|
||||
char tmpCmd[MAX_BUFFER];
|
||||
char tmpCmd[MAX_BUFFER] = {0};
|
||||
size_t cmdLength = strlen(cmdContent);
|
||||
if (cmdLength > MAX_BUFFER - 1) {
|
||||
INIT_LOGE("command line is too larget, should not bigger than %d. ignore...\n", MAX_BUFFER);
|
||||
FreeCmd(&ctx);
|
||||
FreeCmd(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
INIT_CHECK(strncpy_s(tmpCmd, MAX_BUFFER - 1, cmdContent, cmdLength) == EOK,
|
||||
FreeCmd(&ctx);
|
||||
INIT_CHECK(strncpy_s(tmpCmd, MAX_BUFFER - 1, cmdContent, cmdLength) == EOK, FreeCmd(ctx);
|
||||
return NULL);
|
||||
tmpCmd[strlen(cmdContent)] = '\0';
|
||||
|
||||
char *p = tmpCmd;
|
||||
char *token = NULL;
|
||||
size_t allocSize = 0;
|
||||
|
||||
// Skip lead whitespaces
|
||||
while (isspace(*p)) {
|
||||
p++;
|
||||
}
|
||||
SKIP_SPACES(p);
|
||||
ctx->argc = 0;
|
||||
token = strstr(p, delim);
|
||||
if (token == NULL) { // No whitespaces
|
||||
// Make surce there is enough memory to store parameter value
|
||||
allocSize = (size_t)(cmdLength + MAX_PARAM_VALUE_LEN + 1);
|
||||
ctx->argv[ctx->argc] = calloc(sizeof(char), allocSize);
|
||||
INIT_CHECK(ctx->argv[ctx->argc] != NULL, FreeCmd(&ctx); return NULL);
|
||||
INIT_CHECK(GetParamValue(p, ctx->argv[ctx->argc], allocSize) == 0,
|
||||
FreeCmd(&ctx); return NULL);
|
||||
ctx->argc += 1;
|
||||
ctx->argv[ctx->argc] = NULL;
|
||||
return ctx;
|
||||
return CopyCmd(ctx, p, allocSize);
|
||||
}
|
||||
|
||||
int index = ctx->argc;
|
||||
while (token != NULL) {
|
||||
// Too more arguments, treat rest of data as one argument
|
||||
if (index == (argsCount - 1)) {
|
||||
if (ctx->argc == (argsCount - 1)) {
|
||||
break;
|
||||
}
|
||||
*token = '\0'; // replace it with '\0';
|
||||
allocSize = (size_t)((token - p) + MAX_PARAM_VALUE_LEN + 1);
|
||||
ctx->argv[index] = calloc(sizeof(char), allocSize);
|
||||
INIT_CHECK(ctx->argv[index] != NULL, FreeCmd(&ctx); return NULL);
|
||||
INIT_CHECK(GetParamValue(p, ctx->argv[index], allocSize) == 0,
|
||||
FreeCmd(&ctx); return NULL);
|
||||
ctx = CopyCmd(ctx, p, allocSize);
|
||||
INIT_CHECK_RETURN_VALUE(ctx != NULL, NULL);
|
||||
p = token + 1; // skip '\0'
|
||||
// Skip lead whitespaces
|
||||
while (isspace(*p)) {
|
||||
p++;
|
||||
}
|
||||
index++;
|
||||
SKIP_SPACES(p);
|
||||
token = strstr(p, delim);
|
||||
}
|
||||
|
||||
ctx->argc = index;
|
||||
if (p < tmpCmd + cmdLength) {
|
||||
// no more white space or encounter max argument count
|
||||
size_t restSize = tmpCmd + cmdLength - p;
|
||||
allocSize = restSize + MAX_PARAM_VALUE_LEN + 1;
|
||||
ctx->argv[index] = calloc(sizeof(char), allocSize);
|
||||
INIT_CHECK(ctx->argv[index] != NULL, FreeCmd(&ctx); return NULL);
|
||||
INIT_CHECK(GetParamValue(p, ctx->argv[index], allocSize) == 0,
|
||||
FreeCmd(&ctx); return NULL);
|
||||
ctx->argc = index + 1;
|
||||
ctx = CopyCmd(ctx, p, allocSize);
|
||||
INIT_CHECK_RETURN_VALUE(ctx != NULL, NULL);
|
||||
}
|
||||
|
||||
ctx->argv[ctx->argc] = NULL;
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void FreeCmd(struct CmdArgs **cmd)
|
||||
void FreeCmd(struct CmdArgs *cmd)
|
||||
{
|
||||
struct CmdArgs *tmpCmd = *cmd;
|
||||
INIT_CHECK_ONLY_RETURN(tmpCmd != NULL);
|
||||
for (int i = 0; i < tmpCmd->argc; ++i) {
|
||||
INIT_CHECK(tmpCmd->argv[i] == NULL, free(tmpCmd->argv[i]));
|
||||
INIT_CHECK_ONLY_RETURN(cmd != NULL);
|
||||
for (int i = 0; i < cmd->argc; ++i) {
|
||||
INIT_CHECK(cmd->argv[i] == NULL, free(cmd->argv[i]));
|
||||
}
|
||||
INIT_CHECK(tmpCmd->argv == NULL, free(tmpCmd->argv));
|
||||
free(tmpCmd);
|
||||
INIT_CHECK(cmd->argv == NULL, free(cmd->argv));
|
||||
free(cmd);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
#define EXTRACT_ARGS(cmdname, cmdContent, args) \
|
||||
struct CmdArgs *ctx = GetCmd(cmdContent, " ", args); \
|
||||
if ((ctx == NULL) || (ctx->argv == NULL) || (ctx->argc != args)) { \
|
||||
@@ -239,12 +237,12 @@ static void DoSetDomainname(const char *cmdContent, int maxArg)
|
||||
size_t size = strlen(ctx->argv[0]);
|
||||
ssize_t n = write(fd, ctx->argv[0], size);
|
||||
if (n != (ssize_t)size) {
|
||||
INIT_LOGE("DoSetHostname failed to write %s to \"/proc/sys/kernel/domainname\". err = %d", errno);
|
||||
INIT_LOGE("DoSetHostname failed to write %s to \"/proc/sys/kernel/domainname\". err = %d", ctx->argv[0], errno);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
out:
|
||||
FreeCmd(&ctx);
|
||||
FreeCmd(ctx);
|
||||
fd = -1;
|
||||
return;
|
||||
}
|
||||
@@ -262,12 +260,12 @@ static void DoSetHostname(const char *cmdContent, int maxArg)
|
||||
size_t size = strlen(ctx->argv[0]);
|
||||
ssize_t n = write(fd, ctx->argv[0], size);
|
||||
if (n != (ssize_t)size) {
|
||||
INIT_LOGE("DoSetHostname failed to write %s to \"/proc/sys/kernel/hostname\". err = %d", errno);
|
||||
INIT_LOGE("DoSetHostname failed to write %s to \"/proc/sys/kernel/hostname\". err = %d", ctx->argv[0], errno);
|
||||
}
|
||||
|
||||
close(fd);
|
||||
out:
|
||||
FreeCmd(&ctx);
|
||||
FreeCmd(ctx);
|
||||
fd = -1;
|
||||
return;
|
||||
}
|
||||
@@ -303,7 +301,7 @@ static void DoIfup(const char *cmdContent, int maxArg)
|
||||
|
||||
close(fd);
|
||||
out:
|
||||
FreeCmd(&ctx);
|
||||
FreeCmd(ctx);
|
||||
fd = -1;
|
||||
return;
|
||||
}
|
||||
@@ -332,7 +330,7 @@ static void DoSleep(const char *cmdContent, int maxArg)
|
||||
INIT_LOGI("Sleeping %d second(s)", sleepTime);
|
||||
sleep((unsigned int)sleepTime);
|
||||
out:
|
||||
FreeCmd(&ctx);
|
||||
FreeCmd(ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -346,7 +344,7 @@ static void DoStart(const char* cmdContent, int maxArg)
|
||||
INIT_LOGD("DoStart %s", cmdContent);
|
||||
StartServiceByName(cmdContent);
|
||||
out:
|
||||
FreeCmd(&ctx);
|
||||
FreeCmd(ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -360,7 +358,7 @@ static void DoStop(const char* cmdContent, int maxArg)
|
||||
INIT_LOGD("DoStop %s", cmdContent);
|
||||
StopServiceByName(cmdContent);
|
||||
out:
|
||||
FreeCmd(&ctx);
|
||||
FreeCmd(ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -375,7 +373,7 @@ static void DoReset(const char* cmdContent, int maxArg)
|
||||
DoStop(cmdContent, maxArg);
|
||||
DoStart(cmdContent, maxArg);
|
||||
out:
|
||||
FreeCmd(&ctx);
|
||||
FreeCmd(ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -416,7 +414,7 @@ static void DoCopy(const char* cmdContent, int maxArg)
|
||||
}
|
||||
fsync(dstFd);
|
||||
out:
|
||||
FreeCmd(&ctx);
|
||||
FreeCmd(ctx);
|
||||
ctx = NULL;
|
||||
INIT_CHECK(srcFd < 0, close(srcFd); srcFd = -1);
|
||||
INIT_CHECK(dstFd < 0, close(dstFd); dstFd = -1);
|
||||
@@ -440,12 +438,12 @@ static void DoChown(const char* cmdContent, int maxArg)
|
||||
gid_t group = DecodeUid(ctx->argv[1]);
|
||||
INIT_ERROR_CHECK(group != (gid_t)-1, goto out, "DoChown invalid gid :%s.", ctx->argv[1]);
|
||||
|
||||
int pathPos = 2;
|
||||
const int pathPos = 2;
|
||||
if (chown(ctx->argv[pathPos], owner, group) != 0) {
|
||||
INIT_LOGE("DoChown, failed for %s, err %d.", cmdContent, errno);
|
||||
}
|
||||
out:
|
||||
FreeCmd(&ctx);
|
||||
FreeCmd(ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -495,7 +493,7 @@ static void DoMkDir(const char* cmdContent, int maxArg)
|
||||
}
|
||||
}
|
||||
out:
|
||||
FreeCmd(&ctx);
|
||||
FreeCmd(ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -518,7 +516,7 @@ static void DoChmod(const char* cmdContent, int maxArg)
|
||||
INIT_LOGE("DoChmod, failed for %s, err %d.", cmdContent, errno);
|
||||
}
|
||||
out:
|
||||
FreeCmd(&ctx);
|
||||
FreeCmd(ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -675,7 +673,7 @@ static void DoMount(const char* cmdContent, int maxArg)
|
||||
|
||||
#ifndef OHOS_LITE
|
||||
#define OPTIONS_SIZE 128u
|
||||
static void DoInsmodInternal(const char *fileName, char *secondPtr, char *restPtr, int flags)
|
||||
static void DoInsmodInternal(const char *fileName, const char *secondPtr, const char *restPtr, int flags)
|
||||
{
|
||||
char options[OPTIONS_SIZE] = {0};
|
||||
if (flags == 0) { // '-f' option
|
||||
@@ -778,7 +776,7 @@ static void DoSetParam(const char* cmdContent, int maxArg)
|
||||
INIT_LOGE("param name: %s, value %s ", ctx->argv[0], ctx->argv[1]);
|
||||
SystemWriteParam(ctx->argv[0], ctx->argv[1]);
|
||||
out:
|
||||
FreeCmd(&ctx);
|
||||
FreeCmd(ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -886,7 +884,7 @@ static void DoWrite(const char *cmdContent, int maxArg)
|
||||
realPath = NULL;
|
||||
close(fd);
|
||||
out:
|
||||
FreeCmd(&ctx);
|
||||
FreeCmd(ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -905,7 +903,7 @@ static void DoRmdir(const char *cmdContent, int maxArg)
|
||||
goto out;
|
||||
}
|
||||
out:
|
||||
FreeCmd(&ctx);
|
||||
FreeCmd(ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -918,7 +916,7 @@ static void DoRebootCmd(const char *cmdContent, int maxArg)
|
||||
}
|
||||
DoReboot(cmdContent);
|
||||
out:
|
||||
FreeCmd(&ctx);
|
||||
FreeCmd(ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -932,7 +930,7 @@ static void DoLoadPersistParams(const char *cmdContent, int maxArg)
|
||||
INIT_LOGD("load persist params : %s", cmdContent);
|
||||
LoadPersistParams();
|
||||
out:
|
||||
FreeCmd(&ctx);
|
||||
FreeCmd(ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -946,7 +944,7 @@ static void DoTriggerCmd(const char *cmdContent, int maxArg)
|
||||
INIT_LOGD("DoTrigger :%s", cmdContent);
|
||||
DoTriggerExec(cmdContent);
|
||||
out:
|
||||
FreeCmd(&ctx);
|
||||
FreeCmd(ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -960,7 +958,7 @@ static void DoLoadDefaultParams(const char *cmdContent, int maxArg)
|
||||
INIT_LOGD("load persist params : %s", cmdContent);
|
||||
LoadDefaultParams(cmdContent);
|
||||
out:
|
||||
FreeCmd(&ctx);
|
||||
FreeCmd(ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -983,7 +981,7 @@ static void DoSetrlimit(const char *cmdContent, int maxArg)
|
||||
limit.rlim_cur = (rlim_t)atoi(ctx->argv[1]);
|
||||
limit.rlim_max = (rlim_t)atoi(ctx->argv[rlimMaxPos]);
|
||||
int rcs = -1;
|
||||
for (unsigned int i = 0 ; i < sizeof(resource) / sizeof(char*); ++i) {
|
||||
for (unsigned int i = 0; i < ARRAY_LENGTH(resource); ++i) {
|
||||
if (strcmp(ctx->argv[0], resource[i]) == 0) {
|
||||
rcs = (int)i;
|
||||
}
|
||||
@@ -998,7 +996,7 @@ static void DoSetrlimit(const char *cmdContent, int maxArg)
|
||||
goto out;
|
||||
}
|
||||
out:
|
||||
FreeCmd(&ctx);
|
||||
FreeCmd(ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1016,7 +1014,7 @@ static void DoRm(const char *cmdContent, int maxArg)
|
||||
goto out;
|
||||
}
|
||||
out:
|
||||
FreeCmd(&ctx);
|
||||
FreeCmd(ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1034,7 +1032,7 @@ static void DoExport(const char *cmdContent, int maxArg)
|
||||
goto out;
|
||||
}
|
||||
out:
|
||||
FreeCmd(&ctx);
|
||||
FreeCmd(ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1060,7 +1058,7 @@ static void DoExec(const char *cmdContent, int maxArg)
|
||||
if (ret == -1) {
|
||||
INIT_LOGE("DoExec: execute \"%s\" failed: %d.", cmdContent, errno);
|
||||
}
|
||||
FreeCmd(&ctx);
|
||||
FreeCmd(ctx);
|
||||
_exit(0x7f);
|
||||
}
|
||||
return;
|
||||
@@ -1082,7 +1080,7 @@ static void DoSymlink(const char *cmdContent, int maxArg)
|
||||
goto out;
|
||||
}
|
||||
out:
|
||||
FreeCmd(&ctx);
|
||||
FreeCmd(ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1133,7 +1131,7 @@ static void DoMakeNode(const char *cmdContent, int maxArg)
|
||||
goto out;
|
||||
}
|
||||
out:
|
||||
FreeCmd(&ctx);
|
||||
FreeCmd(ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1154,7 +1152,7 @@ static void DoMakeDevice(const char *cmdContent, int maxArg)
|
||||
goto out;
|
||||
}
|
||||
out:
|
||||
FreeCmd(&ctx);
|
||||
FreeCmd(ctx);
|
||||
return;
|
||||
}
|
||||
#endif // __LITEOS__
|
||||
|
||||
@@ -40,7 +40,7 @@ static int ExtractCfgFile(char **cfgFile, const char *content)
|
||||
}
|
||||
#endif
|
||||
|
||||
void ParseAllImports(cJSON *root)
|
||||
void ParseAllImports(const cJSON *root)
|
||||
{
|
||||
cJSON *importAttr = cJSON_GetObjectItemCaseSensitive(root, "import");
|
||||
char *cfgFile = NULL;
|
||||
@@ -79,6 +79,6 @@ void ParseAllImports(cJSON *root)
|
||||
free(cfgFile);
|
||||
cfgFile = NULL;
|
||||
}
|
||||
INIT_LOGD("parse import file done");
|
||||
INIT_LOGD("parse import file done");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -28,12 +28,6 @@
|
||||
#define CMDS_ARR_NAME_IN_JSON "cmds"
|
||||
#define MAX_JOBS_COUNT 100
|
||||
|
||||
// static const char* g_supportedJobs[] = {
|
||||
// "pre-init",
|
||||
// "init",
|
||||
// "post-init",
|
||||
// };
|
||||
|
||||
static Job* g_jobs = NULL;
|
||||
static int g_jobCnt = 0;
|
||||
|
||||
@@ -168,8 +162,6 @@ void DoJob(const char* jobName)
|
||||
for (int j = 0; j < g_jobs[i].cmdLinesCnt; ++j) {
|
||||
DoCmd(&(cmdLines[j]));
|
||||
}
|
||||
// Walk through all jobs
|
||||
// break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,13 +42,13 @@
|
||||
#endif
|
||||
|
||||
#define FILE_NAME_MAX_SIZE 100
|
||||
static void ParseInitCfgContents(cJSON *root)
|
||||
static void ParseInitCfgContents(const cJSON *root)
|
||||
{
|
||||
if (root == NULL) {
|
||||
INIT_LOGE("ParseInitCfgContents root is NULL");
|
||||
return;
|
||||
}
|
||||
// parse services
|
||||
// parse services
|
||||
ParseAllServices(root);
|
||||
#ifdef OHOS_LITE
|
||||
// parse jobs
|
||||
|
||||
@@ -37,7 +37,7 @@ struct RBMiscUpdateMessage {
|
||||
char update[MAX_UPDATE_SIZE];
|
||||
};
|
||||
|
||||
static bool RBMiscWriteUpdaterMessage(const char *path, struct RBMiscUpdateMessage *boot)
|
||||
static bool RBMiscWriteUpdaterMessage(const char *path, const struct RBMiscUpdateMessage *boot)
|
||||
{
|
||||
if (path == NULL || boot == NULL) {
|
||||
INIT_LOGE("path or boot is NULL.");
|
||||
@@ -227,6 +227,5 @@ void DoReboot(const char *value)
|
||||
INIT_LOGE("DoReboot value = %s, error.", value);
|
||||
}
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
+44
-93
@@ -149,113 +149,78 @@ static void OpenConsole()
|
||||
return;
|
||||
}
|
||||
|
||||
static void WriteServicePid(Service *service, pid_t pid)
|
||||
{
|
||||
char pidString[MAX_PID_STRING_LENGTH];
|
||||
INIT_ERROR_CHECK(snprintf_s(pidString, MAX_PID_STRING_LENGTH, MAX_PID_STRING_LENGTH - 1, "%d", pid) >= 0,
|
||||
_exit(0x7f), "Build pid string failed");
|
||||
|
||||
for (int i = 0; i < MAX_WRITEPID_FILES; i++) {
|
||||
if (service->writepidFiles[i] == NULL) {
|
||||
break;
|
||||
}
|
||||
char *realPath = realpath(service->writepidFiles[i], NULL);
|
||||
if (realPath == NULL) {
|
||||
continue;
|
||||
}
|
||||
FILE *fd = fopen(realPath, "wb");
|
||||
free(realPath);
|
||||
realPath = NULL;
|
||||
INIT_ERROR_CHECK(fd != NULL, continue, "Open file %s failed, err = %d", service->writepidFiles[i], errno);
|
||||
INIT_CHECK_ONLY_ELOG(fwrite(pidString, 1, strlen(pidString), fd) == strlen(pidString),
|
||||
"write pid %s to file %s failed, err = %d", pidString, service->writepidFiles[i], errno);
|
||||
(void)fclose(fd);
|
||||
}
|
||||
}
|
||||
|
||||
int ServiceStart(Service *service)
|
||||
{
|
||||
if (service == NULL) {
|
||||
INIT_LOGE("start service failed! null ptr.");
|
||||
return SERVICE_FAILURE;
|
||||
}
|
||||
if (service->pid > 0) {
|
||||
INIT_LOGI("service : %s had started already.", service->name);
|
||||
return SERVICE_SUCCESS;
|
||||
}
|
||||
INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "start service failed! null ptr.");
|
||||
INIT_INFO_CHECK(service->pid <= 0, return SERVICE_SUCCESS, "service : %s had started already.", service->name);
|
||||
if (service->attribute & SERVICE_ATTR_INVALID) {
|
||||
INIT_LOGE("start service %s invalid.", service->name);
|
||||
return SERVICE_FAILURE;
|
||||
}
|
||||
if (service->pathArgs == NULL) {
|
||||
INIT_LOGE("start service pathArgs is NULL.");
|
||||
return SERVICE_FAILURE;
|
||||
}
|
||||
INIT_ERROR_CHECK(service->pathArgs != NULL, return SERVICE_FAILURE, "start service pathArgs is NULL.");
|
||||
struct stat pathStat = {0};
|
||||
service->attribute &= (~(SERVICE_ATTR_NEED_RESTART | SERVICE_ATTR_NEED_STOP));
|
||||
if (stat(service->pathArgs[0], &pathStat) != 0) {
|
||||
service->attribute |= SERVICE_ATTR_INVALID;
|
||||
INIT_LOGE("start service %s invalid, please check %s.",\
|
||||
service->name, service->pathArgs[0]);
|
||||
return SERVICE_FAILURE;
|
||||
}
|
||||
int ret = 0;
|
||||
int pid = fork();
|
||||
INIT_ERROR_CHECK(stat(service->pathArgs[0], &pathStat) == 0, service->attribute |= SERVICE_ATTR_INVALID;
|
||||
return SERVICE_FAILURE, "start service %s invalid, please check %s.", service->name, service->pathArgs[0]);
|
||||
pid_t pid = fork();
|
||||
if (pid == 0) {
|
||||
if (service->socketCfg != NULL) { // start socket service
|
||||
INIT_LOGI("Create socket ");
|
||||
ret = DoCreateSocket(service->socketCfg);
|
||||
if (ret < 0) {
|
||||
INIT_LOGE("DoCreateSocket failed. ");
|
||||
_exit(0x7f); // 0x7f: user specified
|
||||
}
|
||||
INIT_ERROR_CHECK(DoCreateSocket(service->socketCfg) >= 0, _exit(0x7f), "Create Socket failed. ");
|
||||
}
|
||||
if (service->attribute & SERVICE_ATTR_CONSOLE) {
|
||||
OpenConsole();
|
||||
}
|
||||
// permissions
|
||||
if (SetPerms(service) != SERVICE_SUCCESS) {
|
||||
INIT_LOGE("service %s exit! set perms failed! err %d.", service->name, errno);
|
||||
_exit(0x7f); // 0x7f: user specified
|
||||
}
|
||||
char pidString[MAX_PID_STRING_LENGTH]; // writepid
|
||||
pid_t childPid = getpid();
|
||||
if (snprintf_s(pidString, MAX_PID_STRING_LENGTH, MAX_PID_STRING_LENGTH - 1, "%d", childPid) < 0) {
|
||||
INIT_LOGE("start service writepid sprintf failed.");
|
||||
_exit(0x7f); // 0x7f: user specified
|
||||
}
|
||||
for (int i = 0; i < MAX_WRITEPID_FILES; i++) {
|
||||
if (service->writepidFiles[i] == NULL) {
|
||||
continue;
|
||||
}
|
||||
char *realPath = realpath(service->writepidFiles[i], NULL);
|
||||
if (realPath == NULL) {
|
||||
continue;
|
||||
}
|
||||
FILE *fd = fopen(realPath, "wb");
|
||||
if (fd == NULL) {
|
||||
INIT_LOGE("start service writepidFiles %s invalid.", service->writepidFiles[i]);
|
||||
free(realPath);
|
||||
realPath = NULL;
|
||||
continue;
|
||||
}
|
||||
if (fwrite(pidString, 1, strlen(pidString), fd) != strlen(pidString)) {
|
||||
INIT_LOGE("start service writepid error.file:%s pid:%s", service->writepidFiles[i], pidString);
|
||||
}
|
||||
free(realPath);
|
||||
realPath = NULL;
|
||||
fclose(fd);
|
||||
INIT_LOGE("ServiceStart writepid filename=%s, childPid=%s, ok", service->writepidFiles[i],
|
||||
pidString);
|
||||
}
|
||||
|
||||
INIT_ERROR_CHECK(SetPerms(service) == SERVICE_SUCCESS, _exit(0x7f),
|
||||
"service %s exit! set perms failed! err %d.", service->name, errno);
|
||||
WriteServicePid(service, getpid());
|
||||
INIT_LOGI("service->name is %s ", service->name);
|
||||
#ifndef OHOS_LITE
|
||||
if (service->importance != 0) {
|
||||
if (setpriority(PRIO_PROCESS, 0, service->importance) != 0) {
|
||||
INIT_LOGE("setpriority failed for %s, importance = %d", service->name, service->importance);
|
||||
_exit(0x7f); // 0x7f: user specified
|
||||
}
|
||||
INIT_ERROR_CHECK(setpriority(PRIO_PROCESS, 0, service->importance) == 0, _exit(0x7f),
|
||||
"setpriority failed for %s, importance = %d", service->name, service->importance);
|
||||
}
|
||||
// L2 Can not be reset env
|
||||
if (execv(service->pathArgs[0], service->pathArgs) != 0) {
|
||||
INIT_LOGE("service %s execve failed! err %d.", service->name, errno);
|
||||
}
|
||||
INIT_CHECK_ONLY_ELOG(execv(service->pathArgs[0], service->pathArgs) == 0,
|
||||
"service %s execve failed! err %d.", service->name, errno);
|
||||
#else
|
||||
char* env[] = {"LD_LIBRARY_PATH=/storage/app/libs", NULL};
|
||||
if (execve(service->pathArgs[0], service->pathArgs, env) != 0) {
|
||||
INIT_LOGE("service %s execve failed! err %d.", service->name, errno);
|
||||
}
|
||||
INIT_CHECK_ONLY_ELOG(execve(service->pathArgs[0], service->pathArgs, env) == 0,
|
||||
"service %s execve failed! err %d.", service->name, errno);
|
||||
#endif
|
||||
|
||||
_exit(0x7f); // 0x7f: user specified
|
||||
} else if (pid < 0) {
|
||||
INIT_LOGE("start service %s fork failed!", service->name);
|
||||
return SERVICE_FAILURE;
|
||||
}
|
||||
|
||||
service->pid = pid;
|
||||
#ifndef OHOS_LITE
|
||||
char paramName[PARAM_NAME_LEN_MAX] = {0};
|
||||
if (snprintf_s(paramName, PARAM_NAME_LEN_MAX, PARAM_NAME_LEN_MAX - 1, "init.svc.%s", service->name) < 0) {
|
||||
INIT_LOGE("snprintf_s paramName error %d ", errno);
|
||||
}
|
||||
INIT_CHECK_ONLY_ELOG(snprintf_s(paramName, PARAM_NAME_LEN_MAX, PARAM_NAME_LEN_MAX - 1, "init.svc.%s",
|
||||
service->name) >= 0, "snprintf_s paramName error %d ", errno);
|
||||
SystemWriteParam(paramName, "running");
|
||||
#endif
|
||||
return SERVICE_SUCCESS;
|
||||
@@ -338,7 +303,6 @@ void ServiceReap(Service *service)
|
||||
INIT_LOGE("reap service failed! null ptr.");
|
||||
return;
|
||||
}
|
||||
|
||||
service->pid = -1;
|
||||
#ifndef OHOS_LITE
|
||||
char paramName[PARAM_NAME_LEN_MAX] = {0};
|
||||
@@ -351,14 +315,12 @@ void ServiceReap(Service *service)
|
||||
INIT_LOGE("ServiceReap service %s invalid.", service->name);
|
||||
return;
|
||||
}
|
||||
|
||||
// stopped by system-init itself, no need to restart even if it is not one-shot service
|
||||
if (service->attribute & SERVICE_ATTR_NEED_STOP) {
|
||||
service->attribute &= (~SERVICE_ATTR_NEED_STOP);
|
||||
service->crashCnt = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
// for one-shot service
|
||||
if (service->attribute & SERVICE_ATTR_ONCE) {
|
||||
// no need to restart
|
||||
@@ -366,9 +328,7 @@ void ServiceReap(Service *service)
|
||||
service->attribute &= (~SERVICE_ATTR_NEED_STOP);
|
||||
return;
|
||||
}
|
||||
// the service could be restart even if it is one-shot service
|
||||
}
|
||||
|
||||
// the service that does not need to be restarted restarts, indicating that it has crashed
|
||||
if (!(service->attribute & SERVICE_ATTR_NEED_RESTART)) {
|
||||
// crash time and count check
|
||||
@@ -387,20 +347,11 @@ void ServiceReap(Service *service)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CheckCritical(service);
|
||||
int ret = 0;
|
||||
if (service->onRestart != NULL) {
|
||||
ret = ExecRestartCmd(service);
|
||||
if (ret != SERVICE_SUCCESS) {
|
||||
INIT_LOGE("SetOnRestart fail ");
|
||||
}
|
||||
INIT_CHECK_ONLY_ELOG(ExecRestartCmd(service) == SERVICE_SUCCESS, "SetOnRestart fail ");
|
||||
}
|
||||
ret = ServiceStart(service);
|
||||
if (ret != SERVICE_SUCCESS) {
|
||||
INIT_LOGE("reap service %s start failed!", service->name);
|
||||
}
|
||||
|
||||
INIT_CHECK_ONLY_ELOG(ServiceStart(service) == SERVICE_SUCCESS, "reap service %s start failed!", service->name);
|
||||
service->attribute &= (~SERVICE_ATTR_NEED_RESTART);
|
||||
}
|
||||
|
||||
|
||||
@@ -158,7 +158,6 @@ static int IsForbidden(const char* fieldStr)
|
||||
}
|
||||
#endif
|
||||
|
||||
// TODO: move this function to common files
|
||||
static cJSON* GetArrItem(const cJSON* fileRoot, int* arrSize, const char* arrName)
|
||||
{
|
||||
cJSON* arrItem = cJSON_GetObjectItemCaseSensitive(fileRoot, arrName);
|
||||
@@ -260,13 +259,11 @@ static int GetGidArray(const cJSON *curArrItem, Service *curServ) // gid
|
||||
if ((gIDCnt <= 0) || (filedJ == NULL)) { // not a array, but maybe a item?
|
||||
return GetGidOneItem(curArrItem, curServ);
|
||||
}
|
||||
|
||||
if (gIDCnt > NGROUPS_MAX + 1) {
|
||||
INIT_LOGE("GetGidArray, too many gids[cnt %d] for one service, should not exceed %d.",
|
||||
gIDCnt, NGROUPS_MAX + 1);
|
||||
return SERVICE_FAILURE;
|
||||
}
|
||||
|
||||
curServ->servPerm.gIDArray = (gid_t *)malloc(sizeof(gid_t) * gIDCnt);
|
||||
if (curServ->servPerm.gIDArray == NULL) {
|
||||
INIT_LOGE("GetGidArray malloc error");
|
||||
@@ -290,9 +287,7 @@ static int GetGidArray(const cJSON *curArrItem, Service *curServ) // gid
|
||||
}
|
||||
curServ->servPerm.gIDArray[i] = gID;
|
||||
}
|
||||
if (i == gIDCnt) {
|
||||
return SERVICE_SUCCESS;
|
||||
}
|
||||
INIT_CHECK_RETURN_VALUE(i != gIDCnt, SERVICE_SUCCESS);
|
||||
for (i = 0; i < gIDCnt; ++i) {
|
||||
cJSON *item = cJSON_GetArrayItem(filedJ, i);
|
||||
if (item == NULL) {
|
||||
@@ -308,8 +303,7 @@ static int GetGidArray(const cJSON *curArrItem, Service *curServ) // gid
|
||||
}
|
||||
curServ->servPerm.gIDArray[i] = gID;
|
||||
}
|
||||
int ret = i == gIDCnt ? SERVICE_SUCCESS : SERVICE_FAILURE;
|
||||
return ret;
|
||||
return (((i == gIDCnt) ? SERVICE_SUCCESS : SERVICE_FAILURE));
|
||||
}
|
||||
|
||||
static int GetServicePathAndArgs(const cJSON* curArrItem, Service* curServ)
|
||||
@@ -479,16 +473,12 @@ static int GetUidStringNumber(const cJSON *curArrItem, Service *curServ)
|
||||
|
||||
static int ParseServiceSocket(char **opt, const int optNum, struct ServiceSocket *sockopt)
|
||||
{
|
||||
if (optNum != SOCK_OPT_NUMS) {
|
||||
return -1;
|
||||
}
|
||||
if (opt[SERVICE_SOCK_TYPE] == NULL) {
|
||||
return -1;
|
||||
}
|
||||
INIT_CHECK_RETURN_VALUE(optNum == SOCK_OPT_NUMS, -1);
|
||||
INIT_CHECK_RETURN_VALUE(opt[SERVICE_SOCK_TYPE] != NULL, -1);
|
||||
sockopt->type =
|
||||
strncmp(opt[SERVICE_SOCK_TYPE], "stream", strlen(opt[SERVICE_SOCK_TYPE])) == 0 ? SOCK_STREAM :
|
||||
(strncmp(opt[SERVICE_SOCK_TYPE], "dgram", strlen(opt[SERVICE_SOCK_TYPE])) == 0 ? SOCK_DGRAM : SOCK_SEQPACKET);
|
||||
|
||||
((strncmp(opt[SERVICE_SOCK_TYPE], "stream", strlen(opt[SERVICE_SOCK_TYPE])) == 0) ? SOCK_STREAM :
|
||||
((strncmp(opt[SERVICE_SOCK_TYPE], "dgram", strlen(opt[SERVICE_SOCK_TYPE])) == 0) ? SOCK_DGRAM :
|
||||
SOCK_SEQPACKET));
|
||||
if (opt[SERVICE_SOCK_PERM] == NULL) {
|
||||
return -1;
|
||||
}
|
||||
@@ -512,7 +502,8 @@ static int ParseServiceSocket(char **opt, const int optNum, struct ServiceSocket
|
||||
if (opt[SERVICE_SOCK_SETOPT] == NULL) {
|
||||
return -1;
|
||||
}
|
||||
sockopt->passcred = strncmp(opt[SERVICE_SOCK_SETOPT], "passcred", strlen(opt[SERVICE_SOCK_SETOPT])) == 0 ? true : false;
|
||||
sockopt->passcred = (strncmp(opt[SERVICE_SOCK_SETOPT], "passcred",
|
||||
strlen(opt[SERVICE_SOCK_SETOPT])) == 0) ? true : false;
|
||||
if (opt[SERVICE_SOCK_NAME] == NULL) {
|
||||
return -1;
|
||||
}
|
||||
@@ -533,7 +524,7 @@ static int ParseServiceSocket(char **opt, const int optNum, struct ServiceSocket
|
||||
|
||||
static void FreeServiceSocket(struct ServiceSocket *sockopt)
|
||||
{
|
||||
if (!sockopt) {
|
||||
if (sockopt == NULL) {
|
||||
return;
|
||||
}
|
||||
struct ServiceSocket *tmpSock = NULL;
|
||||
@@ -566,13 +557,13 @@ static int GetServiceSocket(const cJSON* curArrItem, Service* curServ)
|
||||
return SERVICE_FAILURE;
|
||||
}
|
||||
char *sockStr = cJSON_GetStringValue(sockJ);
|
||||
char *tmpStr[SOCK_OPT_NUMS] = {NULL,};
|
||||
char *tmpStr[SOCK_OPT_NUMS] = {NULL};
|
||||
int num = SplitString(sockStr, tmpStr, SOCK_OPT_NUMS);
|
||||
if (num != SOCK_OPT_NUMS) {
|
||||
return SERVICE_FAILURE;
|
||||
}
|
||||
struct ServiceSocket *socktmp = (struct ServiceSocket *)calloc(1, sizeof(struct ServiceSocket));
|
||||
if (!socktmp) {
|
||||
if (socktmp == NULL) {
|
||||
return SERVICE_FAILURE;
|
||||
}
|
||||
int ret = ParseServiceSocket(tmpStr, SOCK_OPT_NUMS, socktmp);
|
||||
@@ -632,7 +623,8 @@ static int GetServiceOnRestart(const cJSON* curArrItem, Service* curServ)
|
||||
|
||||
static int CheckServiceKeyName(const cJSON* curService)
|
||||
{
|
||||
char *cfgServiceKeyList[] = {"name", "path", "uid", "gid", "once",
|
||||
char *cfgServiceKeyList[] = {
|
||||
"name", "path", "uid", "gid", "once",
|
||||
"importance", "caps", "disabled", "writepid", "critical", "socket", "console"
|
||||
};
|
||||
if (curService == NULL) {
|
||||
@@ -642,15 +634,15 @@ static int CheckServiceKeyName(const cJSON* curService)
|
||||
if (child == NULL) {
|
||||
return SERVICE_FAILURE;
|
||||
}
|
||||
while (child) {
|
||||
while (child != NULL) {
|
||||
int i = 0;
|
||||
int keyListSize = sizeof(cfgServiceKeyList) / sizeof(char *);
|
||||
int keyListSize = ARRAY_LENGTH(cfgServiceKeyList);
|
||||
for (; i < keyListSize; i++) {
|
||||
if (!strcmp(child->string, cfgServiceKeyList[i])) {
|
||||
if (strcmp(child->string, cfgServiceKeyList[i]) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(i < keyListSize) {
|
||||
if (i < keyListSize) {
|
||||
child = child->next;
|
||||
} else {
|
||||
INIT_LOGE("CheckServiceKeyName, key name %s is not found. error.", child->string);
|
||||
@@ -660,28 +652,40 @@ static int CheckServiceKeyName(const cJSON* curService)
|
||||
return SERVICE_SUCCESS;
|
||||
}
|
||||
|
||||
static int ParseOneService(const cJSON *curItem, Service *service)
|
||||
{
|
||||
if (curItem == NULL || service == NULL) {
|
||||
return SERVICE_FAILURE;
|
||||
}
|
||||
int ret = GetServiceName(curItem, service);
|
||||
ret |= GetServicePathAndArgs(curItem, service);
|
||||
ret |= GetUidStringNumber(curItem, service);
|
||||
ret |= GetGidArray(curItem, service);
|
||||
ret |= GetServiceNumber(curItem, service, ONCE_STR_IN_CFG);
|
||||
ret |= GetServiceNumber(curItem, service, IMPORTANT_STR_IN_CFG);
|
||||
ret |= GetServiceNumber(curItem, service, CRITICAL_STR_IN_CFG);
|
||||
ret |= GetServiceNumber(curItem, service, DISABLED_STR_IN_CFG);
|
||||
ret |= GetServiceNumber(curItem, service, CONSOLE_STR_IN_CFG);
|
||||
ret |= GetWritepidStrings(curItem, service);
|
||||
ret |= GetServiceCaps(curItem, service);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ParseAllServices(const cJSON* fileRoot)
|
||||
{
|
||||
int servArrSize = 0;
|
||||
cJSON* serviceArr = GetArrItem(fileRoot, &servArrSize, SERVICES_ARR_NAME_IN_JSON);
|
||||
if (serviceArr == NULL) {
|
||||
INIT_LOGI("ParseAllServices, this config does not contain service array.");
|
||||
return;
|
||||
}
|
||||
INIT_INFO_CHECK(serviceArr != NULL, return, "This config does not contain service array.");
|
||||
|
||||
INIT_ERROR_CHECK(servArrSize <= MAX_SERVICES_CNT_IN_FILE, return,
|
||||
"Too many services[cnt %d] detected, should not exceed %d.",
|
||||
servArrSize, MAX_SERVICES_CNT_IN_FILE);
|
||||
INIT_CHECK_ONLY_RETURN((g_servicesCnt + servArrSize) > 0);
|
||||
|
||||
if (servArrSize > MAX_SERVICES_CNT_IN_FILE) {
|
||||
INIT_LOGE("ParseAllServices, too many services[cnt %d] detected, should not exceed %d.",
|
||||
servArrSize, MAX_SERVICES_CNT_IN_FILE);
|
||||
return;
|
||||
}
|
||||
if ((g_servicesCnt + servArrSize) <= 0) {
|
||||
return;
|
||||
}
|
||||
Service* retServices = (Service*)realloc(g_services, sizeof(Service) * (g_servicesCnt + servArrSize));
|
||||
if (retServices == NULL) {
|
||||
INIT_LOGE("ParseAllServices, realloc for %s arr failed! %d.", SERVICES_ARR_NAME_IN_JSON, servArrSize);
|
||||
return;
|
||||
}
|
||||
INIT_ERROR_CHECK(retServices != NULL, return,
|
||||
"Realloc for %s arr failed! %d.", SERVICES_ARR_NAME_IN_JSON, servArrSize);
|
||||
|
||||
// Skip already saved services,
|
||||
Service* tmp = retServices + g_servicesCnt;
|
||||
if (memset_s(tmp, sizeof(Service) * servArrSize, 0, sizeof(Service) * servArrSize) != EOK) {
|
||||
@@ -697,28 +701,17 @@ void ParseAllServices(const cJSON* fileRoot)
|
||||
tmp[i].attribute |= SERVICE_ATTR_INVALID;
|
||||
continue;
|
||||
}
|
||||
int ret1 = GetServiceName(curItem, &tmp[i]);
|
||||
int ret2 = GetServicePathAndArgs(curItem, &tmp[i]);
|
||||
int ret3 = GetUidStringNumber(curItem, &tmp[i]); // uid in string or number form
|
||||
int ret4 = GetGidArray(curItem, &tmp[i]); // gid array
|
||||
int ret5 = GetServiceNumber(curItem, &tmp[i], ONCE_STR_IN_CFG);
|
||||
int ret6 = GetServiceNumber(curItem, &tmp[i], IMPORTANT_STR_IN_CFG);
|
||||
int ret7 = GetServiceNumber(curItem, &tmp[i], CRITICAL_STR_IN_CFG); // critical
|
||||
int ret8 = GetServiceNumber(curItem, &tmp[i], DISABLED_STR_IN_CFG); // disabled
|
||||
int ret9 = GetServiceNumber(curItem, &tmp[i], CONSOLE_STR_IN_CFG); // console
|
||||
int reta = GetWritepidStrings(curItem, &tmp[i]); // writepid
|
||||
int retb = GetServiceCaps(curItem, &tmp[i]);
|
||||
int retAll = ret1 | ret2 | ret3 | ret4 | ret5 | ret6 | ret7 | ret8 | ret9 | reta | retb;
|
||||
if (retAll != SERVICE_SUCCESS) {
|
||||
int ret = ParseOneService(curItem, &tmp[i]);
|
||||
if (ret != SERVICE_SUCCESS) {
|
||||
// release resources if it fails
|
||||
ReleaseServiceMem(&tmp[i]);
|
||||
tmp[i].attribute |= SERVICE_ATTR_INVALID;
|
||||
INIT_LOGE("ParseAllServices, parse information for service %s failed. ", tmp[i].name);
|
||||
INIT_LOGE("Parse information for service %s failed. ", tmp[i].name);
|
||||
continue;
|
||||
} else {
|
||||
INIT_LOGD("ParseAllServices ParseAllServices Service[%d] name=%s, uid=%d, critical=%d, disabled=%d",
|
||||
i, tmp[i].name, tmp[i].servPerm.uID, tmp[i].attribute & SERVICE_ATTR_CRITICAL ? 1 : 0,
|
||||
tmp[i].attribute & SERVICE_ATTR_DISABLED ? 1 : 0);
|
||||
INIT_LOGD("service[%d] name=%s, uid=%d, critical=%d, disabled=%d",
|
||||
i, tmp[i].name, tmp[i].servPerm.uID, (tmp[i].attribute & SERVICE_ATTR_CRITICAL) ? 1 : 0,
|
||||
(tmp[i].attribute & SERVICE_ATTR_DISABLED) ? 1 : 0);
|
||||
}
|
||||
if (GetServiceSocket(curItem, &tmp[i]) != SERVICE_SUCCESS) {
|
||||
if (tmp[i].socketCfg != NULL) {
|
||||
@@ -828,4 +821,3 @@ void ReapServiceByPID(int pid)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
static int CreateSocket(struct ServiceSocket *sockopt)
|
||||
{
|
||||
if (!sockopt || !sockopt->name) {
|
||||
if (sockopt == NULL || sockopt->name == NULL) {
|
||||
return -1;
|
||||
}
|
||||
if (sockopt->sockFd >= 0) {
|
||||
@@ -41,19 +41,15 @@ static int CreateSocket(struct ServiceSocket *sockopt)
|
||||
sockopt->sockFd = -1;
|
||||
}
|
||||
sockopt->sockFd = socket(PF_UNIX, sockopt->type, 0);
|
||||
if (sockopt->sockFd < 0) {
|
||||
INIT_LOGE("socket fail %d ", errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
INIT_ERROR_CHECK(sockopt->sockFd >= 0, return -1, "socket fail %d ", errno);
|
||||
struct sockaddr_un addr;
|
||||
bzero(&addr,sizeof(addr));
|
||||
bzero(&addr, sizeof(addr));
|
||||
addr.sun_family = AF_UNIX;
|
||||
if (snprintf_s(addr.sun_path, sizeof(addr.sun_path), sizeof(addr.sun_path) - 1, HOS_SOCKET_DIR"/%s",
|
||||
sockopt->name) < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (access(addr.sun_path, F_OK)) {
|
||||
if (access(addr.sun_path, F_OK) == 0) {
|
||||
INIT_LOGE("%s already exist, remove it", addr.sun_path);
|
||||
if (unlink(addr.sun_path) != 0) {
|
||||
INIT_LOGE("ulink fail err %d ", errno);
|
||||
@@ -67,28 +63,24 @@ static int CreateSocket(struct ServiceSocket *sockopt)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (bind(sockopt->sockFd, (struct sockaddr *)&addr, sizeof(addr))) {
|
||||
INIT_LOGE("Create socket for service %s failed: %d", sockopt->name, errno);
|
||||
unlink(addr.sun_path);
|
||||
close(sockopt->sockFd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (lchown(addr.sun_path, sockopt->uid, sockopt->gid)) {
|
||||
unlink(addr.sun_path);
|
||||
close(sockopt->sockFd);
|
||||
INIT_LOGE("lchown fail %d ", errno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fchmodat(AT_FDCWD, addr.sun_path, sockopt->perm, AT_SYMLINK_NOFOLLOW)) {
|
||||
unlink(addr.sun_path);
|
||||
close(sockopt->sockFd);
|
||||
INIT_LOGE("fchmodat fail %d ", errno);
|
||||
return -1;
|
||||
}
|
||||
INIT_LOGI("CreateSocket success ");
|
||||
return sockopt->sockFd;
|
||||
}
|
||||
|
||||
@@ -117,11 +109,11 @@ static int SetSocketEnv(int fd, const char *name)
|
||||
|
||||
int DoCreateSocket(struct ServiceSocket *sockopt)
|
||||
{
|
||||
if (!sockopt) {
|
||||
if (sockopt == NULL) {
|
||||
return -1;
|
||||
}
|
||||
struct ServiceSocket *tmpSock = sockopt;
|
||||
while (tmpSock) {
|
||||
while (tmpSock != NULL) {
|
||||
int fd = CreateSocket(tmpSock);
|
||||
if (fd < 0) {
|
||||
return -1;
|
||||
|
||||
@@ -59,7 +59,7 @@ int DecodeUid(const char *name)
|
||||
}
|
||||
if (digitFlag) {
|
||||
errno = 0;
|
||||
uid_t result = strtoul(name, 0, 10);
|
||||
uid_t result = strtoul(name, 0, DECIMAL_BASE);
|
||||
if (errno != 0) {
|
||||
return -1;
|
||||
}
|
||||
@@ -128,7 +128,7 @@ char* ReadFileToBuf(const char *configFile)
|
||||
|
||||
int SplitString(char *srcPtr, char **dstPtr, int maxNum)
|
||||
{
|
||||
if ((!srcPtr) || (!dstPtr)){
|
||||
if ((!srcPtr) || (!dstPtr)) {
|
||||
return -1;
|
||||
}
|
||||
char *buf = NULL;
|
||||
|
||||
+1
-1
@@ -66,7 +66,7 @@ static long TimeDiffMs(const struct timespec* tmBefore, const struct timespec* t
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
#ifndef OHOS_LITE
|
||||
if(setenv("UV_THREADPOOL_SIZE", "1", 1) != 0) {
|
||||
if (setenv("UV_THREADPOOL_SIZE", "1", 1) != 0) {
|
||||
INIT_LOGE("set UV_THREADPOOL_SIZE error : %d.", errno);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,14 +15,22 @@
|
||||
|
||||
#include "list.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
void ListInit(struct ListNode *node)
|
||||
{
|
||||
if (node == NULL) {
|
||||
return;
|
||||
}
|
||||
node->next = node;
|
||||
node->prev = node;
|
||||
}
|
||||
|
||||
void ListAddTail(struct ListNode *head, struct ListNode *item)
|
||||
{
|
||||
if (head == NULL || item == NULL) {
|
||||
return;
|
||||
}
|
||||
item->next = head;
|
||||
item->prev = head->prev;
|
||||
head->prev->next = item;
|
||||
@@ -31,6 +39,9 @@ void ListAddTail(struct ListNode *head, struct ListNode *item)
|
||||
|
||||
void ListRemove(struct ListNode *item)
|
||||
{
|
||||
if (item == NULL) {
|
||||
return;
|
||||
}
|
||||
item->next->prev = item->prev;
|
||||
item->prev->next = item->next;
|
||||
}
|
||||
|
||||
+31
-25
@@ -119,7 +119,7 @@ static void HandleUevent(const struct Uevent *uevent)
|
||||
|
||||
static void AddUevent(struct Uevent *uevent, const char *event, size_t len)
|
||||
{
|
||||
if (uevent == NULL || uevent == NULL || len == 0) {
|
||||
if (uevent == NULL || event == NULL || len == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -140,9 +140,9 @@ static void AddUevent(struct Uevent *uevent, const char *event, size_t len)
|
||||
} else if (STARTSWITH(event, "MINOR=")) {
|
||||
uevent->minor = StringToInt(event + strlen("MINOR="), -1);
|
||||
} else if (STARTSWITH(event, "DEVUID")) {
|
||||
uevent->ug.uid = StringToInt(event + strlen("DEVUID="), 0);
|
||||
uevent->ug.uid = (uid_t)StringToInt(event + strlen("DEVUID="), 0);
|
||||
} else if (STARTSWITH(event, "DEVGID")) {
|
||||
uevent->ug.gid = StringToInt(event + strlen("DEVGID="), 0);
|
||||
uevent->ug.gid = (gid_t)StringToInt(event + strlen("DEVGID="), 0);
|
||||
} else if (STARTSWITH(event, "FIRMWARE=")) {
|
||||
uevent->firmware = event + strlen("FIRMWARE=");
|
||||
} else if (STARTSWITH(event, "BUSNUM=")) {
|
||||
@@ -153,7 +153,7 @@ static void AddUevent(struct Uevent *uevent, const char *event, size_t len)
|
||||
// Ignore other events
|
||||
}
|
||||
|
||||
static void ParseUeventMessage(char *buffer, ssize_t length, struct Uevent *uevent)
|
||||
static void ParseUeventMessage(const char *buffer, ssize_t length, struct Uevent *uevent)
|
||||
{
|
||||
if (buffer == NULL || uevent == NULL || length == 0) {
|
||||
// Ignore invalid buffer
|
||||
@@ -168,7 +168,7 @@ static void ParseUeventMessage(char *buffer, ssize_t length, struct Uevent *ueve
|
||||
uevent->devNum = -1;
|
||||
ssize_t pos = 0;
|
||||
while (pos < length) {
|
||||
char *event = buffer + pos;
|
||||
const char *event = buffer + pos;
|
||||
size_t len = strlen(event);
|
||||
if (len == 0) {
|
||||
break;
|
||||
@@ -200,14 +200,20 @@ static void DoTrigger(const char *ueventPath, int sockFd)
|
||||
if (ueventPath == NULL || ueventPath[0] == '\0') {
|
||||
return;
|
||||
}
|
||||
|
||||
int fd = open(ueventPath, O_WRONLY | O_CLOEXEC);
|
||||
char realPath[PATH_MAX] = {0};
|
||||
if (realpath(ueventPath, realPath) == NULL) {
|
||||
if (errno != ENOENT) {
|
||||
INIT_LOGE("Fail resolve %s real path err=%d", ueventPath, errno);
|
||||
return;
|
||||
}
|
||||
}
|
||||
int fd = open(realPath, O_WRONLY | O_CLOEXEC);
|
||||
if (fd < 0) {
|
||||
INIT_LOGE("Open \" %s \" failed, err = %d", ueventPath, errno);
|
||||
INIT_LOGE("Open \" %s \" failed, err = %d", realPath, errno);
|
||||
} else {
|
||||
ssize_t n = write(fd, "add\n", 4);
|
||||
ssize_t n = write(fd, "add\n", strlen("add\n"));
|
||||
if (n < 0) {
|
||||
INIT_LOGE("Write \" %s \" failed, err = %d", ueventPath, errno);
|
||||
INIT_LOGE("Write \" %s \" failed, err = %d", realPath, errno);
|
||||
close(fd);
|
||||
} else {
|
||||
close(fd);
|
||||
@@ -224,27 +230,27 @@ static void Trigger(const char *path, int sockFd)
|
||||
DIR *dir = opendir(path);
|
||||
if (dir != NULL) {
|
||||
struct dirent *dirent = NULL;
|
||||
while ((dirent = readdir(dir)) != NULL) {
|
||||
if (dirent->d_name[0] == '.') {
|
||||
continue;
|
||||
}
|
||||
if (dirent->d_type == DT_DIR) {
|
||||
char pathBuffer[PATH_MAX];
|
||||
if (snprintf_s(pathBuffer, PATH_MAX, PATH_MAX - 1, "%s/%s", path, dirent->d_name) == -1) {
|
||||
continue;
|
||||
}
|
||||
Trigger(pathBuffer, sockFd);
|
||||
} else {
|
||||
if (!strcmp(dirent->d_name, "uevent")) {
|
||||
while ((dirent = readdir(dir)) != NULL) {
|
||||
if (dirent->d_name[0] == '.') {
|
||||
continue;
|
||||
}
|
||||
if (dirent->d_type == DT_DIR) {
|
||||
char pathBuffer[PATH_MAX];
|
||||
if (snprintf_s(pathBuffer, PATH_MAX, PATH_MAX - 1, "%s/%s", path, dirent->d_name) == -1) {
|
||||
continue;
|
||||
}
|
||||
Trigger(pathBuffer, sockFd);
|
||||
} else {
|
||||
if (!strcmp(dirent->d_name, "uevent")) {
|
||||
char ueventBuffer[PATH_MAX];
|
||||
if (snprintf_s(ueventBuffer, PATH_MAX, PATH_MAX - 1, "%s/%s", path, "uevent") == -1) {
|
||||
INIT_LOGW("Cannnot build uevent path under %s", path);
|
||||
continue;
|
||||
}
|
||||
DoTrigger(ueventBuffer, sockFd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(dir);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
*/
|
||||
|
||||
#include "ueventd_device_handler.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <libgen.h>
|
||||
#include <stdbool.h>
|
||||
@@ -104,7 +105,7 @@ static int CreateDeviceNode(const struct Uevent *uevent, const char *deviceNode,
|
||||
INIT_LOGE("Create path \" %s \" failed", devicePath);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
GetDeviceNodePermissions(deviceNode, &uid, &gid, &mode);
|
||||
mode |= isBlock ? S_IFBLK : S_IFCHR;
|
||||
dev_t dev = makedev(major, minor);
|
||||
@@ -112,15 +113,15 @@ static int CreateDeviceNode(const struct Uevent *uevent, const char *deviceNode,
|
||||
rc = mknod(deviceNode, mode, dev);
|
||||
if (rc < 0) {
|
||||
if (errno != EEXIST) {
|
||||
INIT_LOGE("Create device node[%s %d, %d] failed", deviceNode, major, minor, errno);
|
||||
INIT_LOGE("Create device node[%s %d, %d] failed err=%d", deviceNode, major, minor, errno);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
AdjustDeviceNodePermissions(deviceNode, uid, gid, mode);
|
||||
if (symLinks) {
|
||||
if (symLinks != NULL) {
|
||||
CreateSymbolLinks(deviceNode, symLinks);
|
||||
}
|
||||
// No matter what result the symbol links returns,
|
||||
// No matter what result the symbol links returns,
|
||||
// as long as create device node done, just returns success.
|
||||
rc = 0;
|
||||
return rc;
|
||||
@@ -149,9 +150,44 @@ static int RemoveDeviceNode(const char *deviceNode, char **symLinks)
|
||||
return unlink(deviceNode);
|
||||
}
|
||||
|
||||
static char *FindPlatformDeviceName(char *path)
|
||||
{
|
||||
if (INVALIDSTRING(path)) {
|
||||
return NULL;
|
||||
}
|
||||
char *pathTmp = path;
|
||||
if (STARTSWITH(pathTmp, "/sys/devices/platform/")) {
|
||||
pathTmp += strlen("/sys/devices/platform/");
|
||||
return pathTmp;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void BuildDeviceSymbolLinks(char **links, int linkNum, const char *parent, const char *partitionName)
|
||||
{
|
||||
if (linkNum > BLOCKDEVICE_LINKS - 1) {
|
||||
INIT_LOGW("Too many links, ignore");
|
||||
return;
|
||||
}
|
||||
|
||||
// If a block device without partition name.
|
||||
// For now, we will not create symbol link for it.
|
||||
if (!INVALIDSTRING(partitionName)) {
|
||||
links[linkNum] = calloc(sizeof(char), DEVICE_FILE_SIZE);
|
||||
if (links[linkNum] == NULL) {
|
||||
INIT_LOGE("Failed to allocate memory for link, err = %d", errno);
|
||||
return;
|
||||
}
|
||||
if (snprintf_s(links[linkNum], DEVICE_FILE_SIZE, DEVICE_FILE_SIZE - 1,
|
||||
"/dev/block/platform/%s/by-name/%s", parent, partitionName) == -1) {
|
||||
INIT_LOGE("Failed to build link");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static char **GetBlockDeviceSymbolLinks(const struct Uevent *uevent)
|
||||
{
|
||||
if (uevent == NULL || !STRINGEQUAL(uevent->subsystem, "block")) {
|
||||
if (uevent == NULL || uevent->subsystem == NULL || STRINGEQUAL(uevent->subsystem, "block") == 0) {
|
||||
INIT_LOGW("Invalid arguments, Skip to get device symbol links.");
|
||||
return NULL;
|
||||
}
|
||||
@@ -163,7 +199,7 @@ static char **GetBlockDeviceSymbolLinks(const struct Uevent *uevent)
|
||||
// For block device under one platform device.
|
||||
// check subsystem file under directory, see if it links to bus/platform.
|
||||
// For now, only support platform device.
|
||||
char sysPath[SYSPATH_SIZE] = {};
|
||||
char sysPath[SYSPATH_SIZE] = {};
|
||||
if (snprintf_s(sysPath, SYSPATH_SIZE, SYSPATH_SIZE - 1, "/sys%s", uevent->syspath) == -1) {
|
||||
INIT_LOGE("Failed to build sys path for device %s", uevent->syspath);
|
||||
return NULL;
|
||||
@@ -173,6 +209,7 @@ static char **GetBlockDeviceSymbolLinks(const struct Uevent *uevent)
|
||||
int linkNum = 0;
|
||||
if (links == NULL) {
|
||||
INIT_LOGE("Failed to allocate memory for links, err = %d", errno);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Reverse walk through sysPath, and check subystem file under each directory.
|
||||
@@ -185,39 +222,19 @@ static char **GetBlockDeviceSymbolLinks(const struct Uevent *uevent)
|
||||
}
|
||||
|
||||
char *bus = realpath(subsystem, NULL);
|
||||
if (bus == NULL) {
|
||||
goto loop;
|
||||
}
|
||||
|
||||
if (STRINGEQUAL(bus, "/sys/bus/platform")) {
|
||||
INIT_LOGD("Find a platform device: %s", parent);
|
||||
if (STARTSWITH(parent, "/sys/devices/platform/")) {
|
||||
parent += strlen("/sys/devices/platform/");
|
||||
if (linkNum > BLOCKDEVICE_LINKS - 1) {
|
||||
INIT_LOGW("Too much links, ignore");
|
||||
break;
|
||||
}
|
||||
links[linkNum] = calloc(sizeof(char), DEVICE_FILE_SIZE);
|
||||
if (links[linkNum] == NULL) {
|
||||
INIT_LOGE("Failed to allocate memory for link, err = %d", errno);
|
||||
break;
|
||||
}
|
||||
// If a block device without partition name.
|
||||
// For now, we will not create symbol link for it.
|
||||
if (!INVALIDSTRING(uevent->partitionName)) {
|
||||
if (snprintf_s(links[linkNum], DEVICE_FILE_SIZE, DEVICE_FILE_SIZE - 1,
|
||||
"/dev/block/platform/%s/by-name/%s", parent, uevent->partitionName) == -1) {
|
||||
INIT_LOGE("Failed to build link");
|
||||
break;
|
||||
}
|
||||
if (bus != NULL) {
|
||||
if (STRINGEQUAL(bus, "/sys/bus/platform")) {
|
||||
INIT_LOGD("Find a platform device: %s", parent);
|
||||
parent = FindPlatformDeviceName(parent);
|
||||
if (parent != NULL) {
|
||||
BuildDeviceSymbolLinks(links, linkNum, parent, uevent->partitionName);
|
||||
}
|
||||
linkNum++;
|
||||
}
|
||||
}
|
||||
loop:
|
||||
parent = dirname(parent);
|
||||
continue;
|
||||
}
|
||||
|
||||
links[linkNum] = NULL;
|
||||
return links;
|
||||
}
|
||||
@@ -270,7 +287,6 @@ static const char *GetDeviceName(char *sysPath, const char *deviceName)
|
||||
}
|
||||
if (deviceName != NULL && deviceName[0] != '\0') {
|
||||
// if device name reported by kernel includes '/', skip it.
|
||||
// TODO: use entire device name reported by kernel
|
||||
devName = basename((char *)deviceName);
|
||||
char *p = strrchr(deviceName, '/');
|
||||
if (p != NULL) { // device name includes slash
|
||||
@@ -357,7 +373,7 @@ void HandleBlockDeviceEvent(const struct Uevent *uevent)
|
||||
|
||||
void HandleOtherDeviceEvent(const struct Uevent *uevent)
|
||||
{
|
||||
if (uevent == NULL || uevent->subsystem == NULL) {
|
||||
if (uevent == NULL || uevent->subsystem == NULL || uevent->syspath == NULL) {
|
||||
INIT_LOGE("Invalid uevent received");
|
||||
return;
|
||||
}
|
||||
@@ -381,10 +397,10 @@ void HandleOtherDeviceEvent(const struct Uevent *uevent)
|
||||
}
|
||||
INIT_LOGD("HandleOtherDeviceEvent, devPath = %s, devName = %s", devPath, devName);
|
||||
|
||||
// For usb devices, should take care of it specially.
|
||||
// if usb devices report DEVNAME, just create device node.
|
||||
// otherwise, create deviceNode with bus number and device number.
|
||||
if (STRINGEQUAL(uevent->subsystem, "usb")) {
|
||||
// For usb devices, should take care of it specially.
|
||||
// if usb devices report DEVNAME, just create device node.
|
||||
// otherwise, create deviceNode with bus number and device number.
|
||||
if (STRINGEQUAL(uevent->subsystem, "usb")) {
|
||||
if (uevent->deviceName != NULL) {
|
||||
if (snprintf_s(deviceNode, DEVICE_FILE_SIZE, DEVICE_FILE_SIZE - 1, "/dev/%s", uevent->deviceName) == -1) {
|
||||
INIT_LOGE("Make device file for device [%d : %d]", uevent->major, uevent->minor);
|
||||
@@ -396,19 +412,19 @@ void HandleOtherDeviceEvent(const struct Uevent *uevent)
|
||||
INIT_LOGE("usb device with invalid bus number or device number");
|
||||
return;
|
||||
}
|
||||
if (snprintf_s(deviceNode, DEVICE_FILE_SIZE, DEVICE_FILE_SIZE - 1,
|
||||
if (snprintf_s(deviceNode, DEVICE_FILE_SIZE, DEVICE_FILE_SIZE - 1,
|
||||
"/dev/bus/usb/%03d/%03d", uevent->busNum, uevent->devNum) == -1) {
|
||||
INIT_LOGE("Make usb device node for device [%d : %d]", uevent->busNum, uevent->devNum);
|
||||
INIT_LOGE("Make usb device node for device [%d : %d]", uevent->busNum, uevent->devNum);
|
||||
}
|
||||
}
|
||||
} else if (STARTSWITH(uevent->subsystem, "usb")) {
|
||||
// Other usb devies, do not handle it.
|
||||
return;
|
||||
} else {
|
||||
} else if (STARTSWITH(uevent->subsystem, "usb")) {
|
||||
// Other usb devies, do not handle it.
|
||||
return;
|
||||
} else {
|
||||
if (snprintf_s(deviceNode, DEVICE_FILE_SIZE, DEVICE_FILE_SIZE - 1, "%s/%s", devPath, devName) == -1) {
|
||||
INIT_LOGE("Make device file for device [%d : %d]", uevent->major, uevent->minor);
|
||||
return;
|
||||
}
|
||||
}
|
||||
HandleDeviceNode(uevent, deviceNode, false);
|
||||
}
|
||||
HandleDeviceNode(uevent, deviceNode, false);
|
||||
}
|
||||
|
||||
@@ -24,6 +24,5 @@
|
||||
|
||||
void HandleFimwareDeviceEvent(const struct Uevent *uevent)
|
||||
{
|
||||
// TODO, implement it later.
|
||||
INIT_LOGI("Firmware handler not implemented yet.");
|
||||
}
|
||||
|
||||
+64
-39
@@ -14,21 +14,35 @@
|
||||
*/
|
||||
|
||||
#include "ueventd_read_cfg.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include "list.h"
|
||||
#include "ueventd_utils.h"
|
||||
#include "securec.h"
|
||||
#include "ueventd_utils.h"
|
||||
#define INIT_LOG_TAG "ueventd"
|
||||
#include "init_log.h"
|
||||
|
||||
// default item count in config files
|
||||
#define DEFAULTITEMCOUNT (100)
|
||||
|
||||
#define DEVICE_CONFIG_NAME_NUM 0
|
||||
#define DEVICE_CONFIG_MODE_NUM 1
|
||||
#define DEVICE_CONFIG_UID_NUM 2
|
||||
#define DEVICE_CONFIG_GID_NUM 3
|
||||
|
||||
#define SYS_CONFIG_PATH_NUM 0
|
||||
#define SYS_CONFIG_ATTR_NUM 1
|
||||
#define SYS_CONFIG_MODE_NUM 2
|
||||
#define SYS_CONFIG_UID_NUM 3
|
||||
#define SYS_CONFIG_GID_NUM 4
|
||||
|
||||
typedef enum SECTION {
|
||||
SECTION_INVALID = -1,
|
||||
SECTION_DEVICE = 0,
|
||||
@@ -74,23 +88,25 @@ static char **SplitUeventConfig(char *buffer, const char *del, int *returnCount,
|
||||
{
|
||||
char *rest = NULL;
|
||||
int count = 0;
|
||||
int average = 2;
|
||||
int maxItemCountTmp = maxItemCount;
|
||||
char *p = strtok_r(buffer, del, &rest);
|
||||
if (maxItemCount < 0) {
|
||||
if (maxItemCountTmp < 0) {
|
||||
return NULL;
|
||||
}
|
||||
if (maxItemCount > DEFAULTITEMCOUNT) {
|
||||
maxItemCount = DEFAULTITEMCOUNT;
|
||||
if (maxItemCountTmp > DEFAULTITEMCOUNT) {
|
||||
maxItemCountTmp = DEFAULTITEMCOUNT;
|
||||
}
|
||||
char **items = (char **)malloc(sizeof(char*) * maxItemCount);
|
||||
char **items = (char **)malloc(sizeof(char*) * maxItemCountTmp);
|
||||
if (items == NULL) {
|
||||
INIT_LOGE("No enough memory to store uevent config");
|
||||
return NULL;
|
||||
}
|
||||
while (p != NULL) {
|
||||
if (count > maxItemCount - 1) {
|
||||
maxItemCount += (maxItemCount / 2) + 1;
|
||||
if (count > maxItemCountTmp - 1) {
|
||||
maxItemCountTmp += (maxItemCountTmp / average) + 1;
|
||||
INIT_LOGD("Too many items,expand size");
|
||||
char **expand = (char **)(realloc(items, sizeof(char *) * maxItemCount));
|
||||
char **expand = (char **)(realloc(items, sizeof(char *) * maxItemCountTmp));
|
||||
if (expand == NULL) {
|
||||
INIT_LOGE("Failed to expand memory for uevent config parser");
|
||||
FreeConfigItems(items, count);
|
||||
@@ -124,7 +140,7 @@ static int ParseDeviceConfig(char *p)
|
||||
char **items = NULL;
|
||||
int count = -1;
|
||||
// format: <device node> <mode> <uid> <gid>
|
||||
int expectedCount = 4;
|
||||
const int expectedCount = 4;
|
||||
|
||||
if (INVALIDSTRING(p)) {
|
||||
INIT_LOGE("Invalid argument");
|
||||
@@ -142,15 +158,15 @@ static int ParseDeviceConfig(char *p)
|
||||
FreeConfigItems(items, count);
|
||||
return -1;
|
||||
}
|
||||
config->name = strdup(items[0]); // device node
|
||||
config->name = strdup(items[DEVICE_CONFIG_NAME_NUM]); // device node
|
||||
errno = 0;
|
||||
config->mode = strtoul(items[1], NULL, OCTONARY);
|
||||
config->mode = strtoul(items[DEVICE_CONFIG_MODE_NUM], NULL, OCTONARY);
|
||||
if (errno != 0) {
|
||||
INIT_LOGE("Invalid mode in config file for device node %s. use default mode", config->name);
|
||||
config->mode = DEVMODE;
|
||||
}
|
||||
config->uid = StringToInt(items[2], 0);
|
||||
config->gid = StringToInt(items[3], 0);
|
||||
config->uid = (uid_t)StringToInt(items[DEVICE_CONFIG_UID_NUM], 0);
|
||||
config->gid = (gid_t)StringToInt(items[DEVICE_CONFIG_GID_NUM], 0);
|
||||
ListAddTail(&g_devices, &config->list);
|
||||
FreeConfigItems(items, count);
|
||||
return 0;
|
||||
@@ -179,17 +195,18 @@ static int ParseSysfsConfig(char *p)
|
||||
FreeConfigItems(items, count);
|
||||
return -1;
|
||||
}
|
||||
config->sysPath = strdup(items[0]); // sys path
|
||||
config->attr = strdup(items[1]); // attribute
|
||||
config->sysPath = strdup(items[SYS_CONFIG_PATH_NUM]); // sys path
|
||||
config->attr = strdup(items[SYS_CONFIG_ATTR_NUM]); // attribute
|
||||
errno = 0;
|
||||
config->mode = strtoul(items[2], NULL, OCTONARY);
|
||||
config->mode = strtoul(items[SYS_CONFIG_MODE_NUM], NULL, OCTONARY);
|
||||
if (errno != 0) {
|
||||
INIT_LOGE("Invalid mode in config file for sys path %s. use default mode", config->sysPath);
|
||||
config->mode = DEVMODE;
|
||||
}
|
||||
config->uid = StringToInt(items[3], 0);
|
||||
config->gid = StringToInt(items[4], 0);
|
||||
config->uid = (uid_t)StringToInt(items[SYS_CONFIG_UID_NUM], 0);
|
||||
config->gid = (gid_t)StringToInt(items[SYS_CONFIG_GID_NUM], 0);
|
||||
ListAddTail(&g_sysDevices, &config->list);
|
||||
FreeConfigItems(items, count);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -199,12 +216,6 @@ static int ParseFirmwareConfig(char *p)
|
||||
if (INVALIDSTRING(p)) {
|
||||
INIT_LOGE("Invalid argument");
|
||||
}
|
||||
struct FirmwareUdevConf *config = calloc(1, sizeof(struct FirmwareUdevConf));
|
||||
if (config == NULL) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Sanity checks
|
||||
struct stat st = {};
|
||||
if (stat(p, &st) != 0) {
|
||||
@@ -217,12 +228,18 @@ static int ParseFirmwareConfig(char *p)
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct FirmwareUdevConf *config = calloc(1, sizeof(struct FirmwareUdevConf));
|
||||
if (config == NULL) {
|
||||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
config->fmPath = strdup(p);
|
||||
ListAddTail(&g_firmwares, &config->list);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SECTION GetSection(char *section)
|
||||
static SECTION GetSection(const char *section)
|
||||
{
|
||||
if (INVALIDSTRING(section)) {
|
||||
return SECTION_INVALID;
|
||||
@@ -273,14 +290,17 @@ int ParseUeventConfig(char *buffer)
|
||||
callback = funcMapper[type].func;
|
||||
return 0;
|
||||
}
|
||||
return callback != NULL ? callback(p) : -1;
|
||||
return (callback != NULL) ? callback(p) : -1;
|
||||
}
|
||||
|
||||
static void DoUeventConfigParse(char *buffer)
|
||||
static void DoUeventConfigParse(char *buffer, size_t length)
|
||||
{
|
||||
if (length < 0) {
|
||||
return;
|
||||
}
|
||||
char **items = NULL;
|
||||
int count = -1;
|
||||
int maxItemCount = DEFAULTITEMCOUNT;
|
||||
const int maxItemCount = DEFAULTITEMCOUNT;
|
||||
|
||||
items = SplitUeventConfig(buffer, "\n", &count, maxItemCount);
|
||||
INIT_LOGD("Dump items count = %d", count);
|
||||
@@ -309,10 +329,15 @@ void ParseUeventdConfigFile(const char *file)
|
||||
if (INVALIDSTRING(file)) {
|
||||
return;
|
||||
}
|
||||
|
||||
int fd = open(file, O_RDONLY | O_CLOEXEC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||
char realPath[PATH_MAX] = {0};
|
||||
if (realpath(file, realPath) == NULL) {
|
||||
if (errno != ENOENT) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
int fd = open(realPath, O_RDONLY | O_CLOEXEC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||
if (fd < 0) {
|
||||
INIT_LOGE("Read from %s failed", file);
|
||||
INIT_LOGE("Read from %s failed", realPath);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -333,7 +358,7 @@ void ParseUeventdConfigFile(const char *file)
|
||||
}
|
||||
|
||||
if (read(fd, buffer, size) != (ssize_t)size) {
|
||||
INIT_LOGE("Read from file %s failed. err = %d", file, errno);
|
||||
INIT_LOGE("Read from file %s failed. err = %d", realPath, errno);
|
||||
free(buffer);
|
||||
buffer = NULL;
|
||||
close(fd);
|
||||
@@ -341,7 +366,7 @@ void ParseUeventdConfigFile(const char *file)
|
||||
}
|
||||
|
||||
buffer[size] = '\0';
|
||||
DoUeventConfigParse(buffer);
|
||||
DoUeventConfigParse(buffer, size);
|
||||
free(buffer);
|
||||
buffer = NULL;
|
||||
close(fd);
|
||||
@@ -361,11 +386,11 @@ void GetDeviceNodePermissions(const char *devNode, uid_t *uid, gid_t *gid, mode_
|
||||
*uid = config->uid;
|
||||
*gid = config->gid;
|
||||
*mode = config->mode;
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
void ChangeSysAttributePermissions(const char *sysPath)
|
||||
@@ -380,7 +405,7 @@ void ChangeSysAttributePermissions(const char *sysPath)
|
||||
ForEachListEntry(&g_sysDevices, node) {
|
||||
config = ListEntry(node, struct SysUdevConf, list);
|
||||
if (STRINGEQUAL(config->sysPath, sysPath)) {
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,11 +30,13 @@
|
||||
#define INIT_LOG_TAG "ueventd"
|
||||
#include "init_log.h"
|
||||
|
||||
#define UEVENT_SOCKET_BUFF_SIZE (256 * 1024)
|
||||
|
||||
int UeventdSocketInit()
|
||||
{
|
||||
struct sockaddr_nl addr;
|
||||
int sockfd;
|
||||
int buffSize = 256 * 1024;
|
||||
int buffSize = UEVENT_SOCKET_BUFF_SIZE;
|
||||
int on = 1;
|
||||
|
||||
if (memset_s(&addr, sizeof(addr), 0, sizeof(addr) != EOK)) {
|
||||
@@ -46,7 +48,6 @@ int UeventdSocketInit()
|
||||
addr.nl_groups = 0xffffffff;
|
||||
|
||||
sockfd = socket(PF_NETLINK, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, NETLINK_KOBJECT_UEVENT);
|
||||
|
||||
if (sockfd < 0) {
|
||||
INIT_LOGE("Create socket failed, err = %d", errno);
|
||||
return -1;
|
||||
@@ -55,7 +56,7 @@ int UeventdSocketInit()
|
||||
setsockopt(sockfd, SOL_SOCKET, SO_RCVBUFFORCE, &buffSize, sizeof(buffSize));
|
||||
setsockopt(sockfd, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));
|
||||
|
||||
if(bind(sockfd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
|
||||
if (bind(sockfd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
|
||||
INIT_LOGE("Bind socket failed, err = %d", errno);
|
||||
close(sockfd);
|
||||
return -1;
|
||||
@@ -70,7 +71,6 @@ ssize_t ReadUeventMessage(int sockFd, char *buffer, size_t length)
|
||||
struct iovec iov;
|
||||
struct sockaddr_nl addr;
|
||||
char credMsg[CMSG_SPACE(sizeof(struct ucred))];
|
||||
struct cmsghdr *cmsghdr;
|
||||
|
||||
// sanity check
|
||||
if (sockFd < 0 || buffer == NULL) {
|
||||
@@ -90,7 +90,7 @@ ssize_t ReadUeventMessage(int sockFd, char *buffer, size_t length)
|
||||
if (n <= 0) {
|
||||
return n;
|
||||
}
|
||||
cmsghdr = CMSG_FIRSTHDR(&msghdr);
|
||||
struct cmsghdr *cmsghdr = CMSG_FIRSTHDR(&msghdr);
|
||||
if (cmsghdr == NULL || cmsghdr->cmsg_type != SCM_CREDENTIALS) {
|
||||
INIT_LOGE("Unexpected control message, ignored");
|
||||
// Drop this message
|
||||
|
||||
@@ -59,7 +59,7 @@ int MakeDirRecursive(const char *dir, mode_t mode)
|
||||
if (gap < 0) { // end with '/'
|
||||
break;
|
||||
}
|
||||
if (memcpy_s(buffer, PATH_MAX, dir, p - dir -1) != 0) {
|
||||
if (memcpy_s(buffer, PATH_MAX, dir, p - dir - 1) != 0) {
|
||||
return -1;
|
||||
}
|
||||
rc = MakeDir(buffer, mode);
|
||||
@@ -78,5 +78,5 @@ int StringToInt(const char *str, int defaultValue)
|
||||
}
|
||||
errno = 0;
|
||||
int value = strtoul(str, NULL, DECIMALISM);
|
||||
return errno != 0 ? defaultValue : value;
|
||||
return (errno != 0) ? defaultValue : value;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user