From 17cf21bcf8a2e29d2cbcf0a313474d2a4ee44f5d Mon Sep 17 00:00:00 2001 From: Tadao Tanikawa Date: Fri, 20 Nov 2020 23:36:23 +0900 Subject: Re-organized sub-directory by category Since all the sub-directories were placed in the first level, created sub-directories, "hal", "module", and "service" for classification and relocated each component. Signed-off-by: Tadao Tanikawa Change-Id: Ifdf743ac0d1893bd8e445455cf0d2c199a011d5c --- .../task_manager/server/src/tskm_port_pf.cpp | 884 +++++++++++++++++++++ 1 file changed, 884 insertions(+) create mode 100755 service/system/task_manager/server/src/tskm_port_pf.cpp (limited to 'service/system/task_manager/server/src/tskm_port_pf.cpp') diff --git a/service/system/task_manager/server/src/tskm_port_pf.cpp b/service/system/task_manager/server/src/tskm_port_pf.cpp new file mode 100755 index 0000000..f427255 --- /dev/null +++ b/service/system/task_manager/server/src/tskm_port_pf.cpp @@ -0,0 +1,884 @@ +/* + * @copyright Copyright (c) 2016-2020 TOYOTA MOTOR CORPORATION. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "tskm_port_pf.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "system_service/tskm_svc.h" +#include "tskm_debug.h" + +#define TSKM_PORTPF_IN() TSKM_PRINTF(TSKM_LOG_PORTPF, "%s:IN", __FUNCTION__) +#define TSKM_PORTPF_IN_ARG(format, ...) TSKM_PRINTF(TSKM_LOG_PORTPF, "%s:IN:" format, __FUNCTION__, __VA_ARGS__) +#define TSKM_PORTPF_OUT() TSKM_PRINTF(TSKM_LOG_PORTPF, "%s:OUT", __FUNCTION__) + +#define TSKM_PRIO_MIN 1 +#define TSKM_PRIO_MAX 99 +#define TSKM_PRIO_MIN_TSS -20 +#define TSKM_PRIO_MAX_TSS 19 + +#define TSKM_TMP_DIRECTORY "/tmp" +#define TSKM_TMP_TSKM_DIRECTORY TSKM_TMP_DIRECTORY "/tskm" +#define TSKM_TMP_NV_INFO_FILEPATH TSKM_TMP_TSKM_DIRECTORY "/nvInfo" + +#define TSKM_NPP_NV_FILE_TAG SS_TASK_MANAGER "/nvInfo" + +/********************************************************* + * user->uid/gid conversion + *********************************************************/ +TSKM_STATIC int cnvUserName2UidGid(const char *user, uid_t *uid, gid_t *gid) { + int ret = -1; + + if (0 == strcmp(user, "")) { + *uid = geteuid(); + *gid = getegid(); + } else { + static __thread size_t bufSize = 0; + static __thread char *buf = NULL; + struct passwd pwd; + struct passwd *result; + + if (0 == bufSize) { + struct stat statInfo; + + bufSize = -1; + + if (0 != stat("/etc/passwd", &statInfo) || 0 >= statInfo.st_size) { // LCOV_EXCL_START 8: Because buf is a static variable and cannot be passed test + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + TSKM_ASSERT_ERRNO(0); + goto ERROR; + } + // LCOV_EXCL_STOP + + bufSize = statInfo.st_size * 2; + + // Since TaskManager is a resident service, the area allocated here is expected to be released at process termination and is not explicitly released by free() + buf = (char *) malloc(sizeof(char) * bufSize); // NOLINT (runtime/printf) + if (NULL == buf) { // LCOV_EXCL_BR_LINE 5: Error branching of the standard-function malloc + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + TSKM_ASSERT_ERRNO(0); // LCOV_EXCL_LINE 5: Error branching of the standard-function malloc + goto ERROR; // LCOV_EXCL_LINE 5: Error branching of the standard-function malloc + } + } + + if (NULL == buf) { // LCOV_EXCL_BR_LINE 8: Because buf is a static variable and cannot be passed test + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + TSKM_ASSERT(0); // LCOV_EXCL_LINE 8: Because buf is a static variable and cannot be passed test + goto ERROR; // LCOV_EXCL_LINE 8: Because buf is a static variable and cannot be passed test + } + + ret = getpwnam_r(user, &pwd, buf, bufSize, &result); + if (ret != 0 || result == NULL) { + TSKM_ASSERT_PRINT(0, "ret = %d[%s]", ret, user); + goto ERROR; + } + + *uid = pwd.pw_uid; + *gid = pwd.pw_gid; + } + + ret = 0; + + ERROR: + + return ret; +} + +/********************************************************* + * Convert Scheduling Policy Definitions Values (TSKM -> CL) + *********************************************************/ +TSKM_STATIC CL_ProcessSchedPolicy_t cnvTskmPolicy2ClPolicy( + TSKM_SVC_POLICY_t policy) { + switch (policy) { + case TSKM_SVC_POLICY_FIFO: + return CL_PROCESS_SCHED_POLICY_FIFO; + case TSKM_SVC_POLICY_TSS: + return CL_PROCESS_SCHED_POLICY_OTHER; + case TSKM_SVC_POLICY_RR: + return CL_PROCESS_SCHED_POLICY_RR; + default: + TSKM_ASSERT(0); + break; + } + return CL_PROCESS_SCHED_POLICY_OTHER; +} + +/********************************************************* + * Process priority valid value determination + *********************************************************/ +TSKM_STATIC int chkPrioValue(TSKM_SVC_POLICY_t policy, int prio) { + switch (policy) { + case TSKM_SVC_POLICY_FIFO: + case TSKM_SVC_POLICY_RR: + if ((TSKM_PRIO_MIN > prio) || (prio > TSKM_PRIO_MAX)) { + TSKM_ASSERT(0); + } + break; + case TSKM_SVC_POLICY_TSS: + default: + if ((TSKM_PRIO_MIN_TSS > prio) || (prio > TSKM_PRIO_MAX_TSS)) { + TSKM_ASSERT(0); + } + break; + } + + return prio; +} + +/********************************************************* + * COMMONLIB initialization (at system startup) + *********************************************************/ +int tskm_pf_sysInit() { + int fd = 0; + int ret = 0; + + TSKM_PORTPF_IN(); + + fd = CL_ProcessInit(); + if (fd == -1) { // LCOV_EXCL_BR_LINE 6: Error branching during process initialization + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + TSKM_ASSERT_ERRNO(0); // LCOV_EXCL_LINE 6: Error branching during process initialization + goto ERROR; // LCOV_EXCL_LINE 6: Error branching during process initialization + } + + ret = CL_MonitorInit(CL_MONITOR_INIT_USER); + if (ret != 0) { // LCOV_EXCL_BR_LINE 4: NSFW error case. + TSKM_ASSERT_ERRNO(0); + } + + TSKM_PORTPF_OUT(); + return fd; + // LCOV_EXCL_START 6: Error branching during process initialization + ERROR: + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + return -1; + // LCOV_EXCL_STOP +} + +/********************************************************* + * COMMONLIB initialization (at process startup) + *********************************************************/ +int tskm_pf_procInit() { + TSKM_PORTPF_IN(); + // Originally called the _sys_Setup_CWORD64_API (NULL), but changed to empty function along to derete "_sys" + + TSKM_PORTPF_OUT(); + return 0; +} + +/********************************************************* + * Process startup + *********************************************************/ +pid_t tskm_pf_createProc(TSKM_SVC_ATTR_t* p_svcAttr) { + TSKM_PORTPF_IN(); + pid_t retPid = -1; + pid_t pid = -1; + + CL_ProcessAttr_t attr; + char procPath[255]; + char* procName; + uid_t setUid = 0; + gid_t setGid = 0; + + if (0 != CL_ProcessCreateAttrInit(&attr)) { // LCOV_EXCL_BR_LINE 6: Error branching during process initialization + // LCOV_EXCL_START 6: Error branching during process initialization + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + TSKM_ASSERT(0); + goto ERROR; + // LCOV_EXCL_STOP + } + + // Process name setting(from basename) + if (strlen(p_svcAttr->path) < sizeof(procPath)) { + strcpy(procPath, p_svcAttr->path); // NOLINT (runtime/printf) + } else { + TSKM_ASSERT(0); + goto ERROR; + } + + procName = basename(procPath); + if (strlen(procName) >= 16) { + TSKM_ASSERT(0); + procName[16] = '\0'; + } + + if (0 != CL_ProcessCreateAttrSetName(&attr, procName)) { // LCOV_EXCL_BR_LINE 4: NSFW error case. + // LCOV_EXCL_START 4: NSFW error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + TSKM_ASSERT_ERRNO(0); + goto ERROR; + // LCOV_EXCL_STOP + } + + if (0 != cnvUserName2UidGid(p_svcAttr->user, &setUid, &setGid)) { // LCOV_EXCL_BR_LINE 4: NSFW error case. + // LCOV_EXCL_START 4: NSFW error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + TSKM_ASSERT(0); + setUid = geteuid(); + setGid = getegid(); + // LCOV_EXCL_STOP + } + + if (0 != CL_ProcessCreateAttrSetUid(&attr, setUid)) { // LCOV_EXCL_BR_LINE 4: NSFW error case. + // LCOV_EXCL_START 4: NSFW error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + TSKM_ASSERT_ERRNO(0); + goto ERROR; + // LCOV_EXCL_STOP + } + + if (0 != CL_ProcessCreateAttrSetGid(&attr, setGid)) { // LCOV_EXCL_BR_LINE 4: NSFW error case. + // LCOV_EXCL_START 4: NSFW error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + TSKM_ASSERT_ERRNO(0); + goto ERROR; + // LCOV_EXCL_STOP + } + + // All are group leaders in order to recover to the child processes of the service + if (0 != CL_ProcessCreateAttrSetGroup(&attr, 1)) { // LCOV_EXCL_BR_LINE 4: NSFW error case. + // LCOV_EXCL_START 4: NSFW error case. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + TSKM_ASSERT_ERRNO(0); + goto ERROR; + // LCOV_EXCL_STOP + } + if (0 != CL_ProcessCreateAttrSetCpuAssign(&attr, p_svcAttr->cpuAssign)) { + TSKM_ASSERT_ERRNO(0); + goto ERROR; + } + + if (0 + != CL_ProcessCreateAttrSetSchedule( + &attr, cnvTskmPolicy2ClPolicy(p_svcAttr->policy), + chkPrioValue(p_svcAttr->policy, p_svcAttr->prio))) { + TSKM_ASSERT_ERRNO(0); + goto ERROR; + } + + pid = CL_ProcessCreate(p_svcAttr->path, p_svcAttr->args, NULL, &attr); + if (pid == -1) { + TSKM_ASSERT_ERRNO(0); + goto ERROR; + } + + retPid = pid; + ERROR: + + TSKM_PORTPF_OUT(); + return retPid; +} + +/********************************************************* + * Recover termination processes + *********************************************************/ +int tskm_pf_cleanupProc(int sigFd, pid_t* p_pid, TSKM_ERR_t* p_err) { + int ret; + CL_ProcessCleanupInfo_t info; + + ret = CL_ProcessCleanup(sigFd, &info); + if (ret != 0 && ret != 1) { + TSKM_ASSERT_PRINT(0, "ret = %d", ret); + TSKM_ASSERT_ERRNO(0); + goto ERROR; + } + + TSKM_PRINTF(TSKM_LOG_STATE, "SVC TERM:pid:%d code:%d status:%d", info.pid, + info.code, info.status); + + switch (info.code) { + case CLD_STOPPED: + // Not comes here usually + TSKM_PRINTF(TSKM_LOG_STATE, "svc stoped\n"); + goto ERROR; + case CLD_TRAPPED: + // Comes here only during debugging + TSKM_PRINTF(TSKM_LOG_STATE, "svc traped\n"); + goto ERROR; + case CLD_CONTINUED: + // Not comes here usually + TSKM_PRINTF(TSKM_LOG_STATE, "svc continue\n"); + goto ERROR; + default: + break; + } + + *p_pid = info.pid; + *p_err = + (info.code != CLD_EXITED) ? TSKM_E_NG : + (info.code == CLD_EXITED && info.status != EXIT_SUCCESS) ? + TSKM_E_NG : TSKM_E_OK; + + if (TSKM_E_OK != *p_err) { + TSKM_PRINTF(TSKM_LOG_SYSTEMDATA, "SVC ERR TERM:pid:%d code:%d status:%d", + info.pid, info.code, info.status); + } + + return ret; + ERROR: return -1; +} + +/********************************************************* + * Force Terminating a Process Group + *********************************************************/ +int tskm_pf_terminateProcGroup(uint16_t pid) { + int ret; + pid_t pgid; + + pgid = getpgid(pid); + if (pgid < 0) { + TSKM_ASSERT(0); + goto ERROR; + } + + TSKM_PRINTF(TSKM_LOG_STATE, "TERM SVC GROUP:pid:%dpgid:%d", pid, pgid); + + ret = CL_ProcessEuthanizeGroup(pgid); + if (ret != 0) { + TSKM_ASSERT_ERRNO(0); + goto ERROR; + } + + return 0; + ERROR: return -1; +} + +/********************************************************* + * Opening shared memory and trancating + *********************************************************/ +int tskm_pf_shmCreate_Open_Ftrn(const char* name, int32_t size, void** p_addr) { + int ret = 0; + int fd = 0; + + fd = shm_open(name, O_CREAT | O_RDWR | O_TRUNC, S_IRWXU | S_IRWXG | S_IRWXO); + if (fd == -1) { // LCOV_EXCL_BR_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + TSKM_ASSERT_ERRNO(0); // LCOV_EXCL_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded. + ret = -1; // LCOV_EXCL_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded. + if (fd > 0) { // LCOV_EXCL_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded. + TSKM_ASSERT_ERRNO(close(fd) == 0); // LCOV_EXCL_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded. + } // LCOV_EXCL_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded. + return ret; // LCOV_EXCL_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded. + } + + ret = ftruncate(fd, size); + if (ret != 0) { // LCOV_EXCL_BR_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded. + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + TSKM_ASSERT_ERRNO(0); // LCOV_EXCL_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded. + if (fd > 0) { // LCOV_EXCL_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded. + TSKM_ASSERT_ERRNO(close(fd) == 0); // LCOV_EXCL_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded. + } // LCOV_EXCL_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded. + return ret; // LCOV_EXCL_LINE 5: Checked in Death testing, but it is not reflected in the coverage and excluded. + } + + if (p_addr) { // LCOV_EXCL_BR_LINE 8: Because p_addr is set to NULL only + // LCOV_EXCL_START 8: Because p_addr is set to NULL only + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + // Not supported + TSKM_ASSERT_ERRNO(0); + ret = -1; + if (fd > 0) { + TSKM_ASSERT_ERRNO(close(fd) == 0); + } + return ret; + // LCOV_EXCL_STOP + } + + ret = 0; + if (fd > 0) { + TSKM_ASSERT_ERRNO(close(fd) == 0); + } + return ret; +} + +/********************************************************* + * Creating shared memory + *********************************************************/ +int tskm_pf_shmCreate(const char* name, int32_t size, void** p_addr) { + TSKM_PORTPF_IN_ARG("%s,%d", name, size); + struct stat statInfo; + int ret = -1; + + if (stat(name, &statInfo) == 0) { + TSKM_ASSERT_PRINT(0, "Already Exist %s", name); + ret = 0; // To be Succeeded + TSKM_PORTPF_OUT(); + return ret; + } + + ret = tskm_pf_shmCreate_Open_Ftrn(name, size, p_addr); + + TSKM_PORTPF_OUT(); + return ret; +} + +/********************************************************* + * Deleting shared memory + *********************************************************/ +int tskm_pf_shmDelete(const char* name) { + TSKM_PORTPF_IN_ARG("%s", name); + int ret = 0; + + if (0 != shm_unlink(name)) { + TSKM_ASSERT_ERRNO(0); + } + + TSKM_PORTPF_OUT(); + return ret; +} + +/********************************************************* + * Starting thread + *********************************************************/ +int tskm_pf_createThread(void* (*threadFunc)(void*), void* prm, + uint32_t priority, const char* threadName, + pthread_t* p_thId) { + TSKM_PORTPF_IN(); + + int ret; + CL_ThreadAttr_t cl_attr; + + ret = CL_ThreadCreateAttrInit(&cl_attr); + if (ret != 0) { // LCOV_EXCL_BR_LINE 6: For processing initializing process + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + TSKM_ASSERT_ERRNO(0); // LCOV_EXCL_LINE 6: For processing initializing process + goto ERROR; // LCOV_EXCL_LINE 6: For processing initializing process + } + + if (threadName) { + ret = CL_ThreadCreateAttrSetName(&cl_attr, threadName); + TSKM_ASSERT_ERRNO(ret == 0); + } + + ret = CL_ThreadCreate(p_thId, NULL, &cl_attr, threadFunc, prm); + if (ret != 0) { // LCOV_EXCL_BR_LINE 6: For processing initializing process + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + TSKM_ASSERT_ERRNO(0); // LCOV_EXCL_LINE 6: For processing initializing process + goto ERROR; // LCOV_EXCL_LINE 6: For processing initializing process + } + int sched_policy; + struct sched_param sparam; + + pthread_getschedparam(*p_thId, &sched_policy, &sparam); + + sparam.sched_priority = priority; + if ((priority != 0) && (sched_policy == SCHED_OTHER)) { + sched_policy = SCHED_FIFO; + } else if ((priority == 0) && (sched_policy != SCHED_OTHER)) { + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + sched_policy = SCHED_OTHER; // LCOV_EXCL_LINE 6: For processing initializing process + } + + ret = pthread_setschedparam(*p_thId, sched_policy, &sparam); + TSKM_ASSERT(ret == 0); + TSKM_PORTPF_OUT(); + return 0; + ERROR: return -1; +} +/********************************************************* + * Send Stop Complete Response + *********************************************************/ +int tskm_pf_sendStopCompResp() { + EFrameworkunifiedStatus l_eStatus; + TSKM_PORTPF_IN(); + + l_eStatus = SendInterfaceunifiedOnStopResponseToSystemManager(eFrameworkunifiedStatusOK); + if (l_eStatus != eFrameworkunifiedStatusOK) { + TSKM_ASSERT(0); + } + + TSKM_PORTPF_OUT(); + return 0; +} + +/********************************************************* + * ABORT + *********************************************************/ +int tskm_pf_abort() { + TSKM_PORTPF_IN(); + + TSKM_ASSERT(0); + sleep(1); // Sleep a little so that the logging at the time of abnormality may be interrupted + + // Issure SIGSEG + printf("%d\n", *(int *) 0); // NOLINT (readability/casting) + + TSKM_PORTPF_OUT(); + return 0; +} + +/********************************************************* + * EXIT + *********************************************************/ +int tskm_pf_exit(int status) { //LCOV_EXCL_START 5: Checked in Death testing, but it is not reflected in the coverage and excluded + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + TSKM_PORTPF_IN(); + + exit(status); + + TSKM_PORTPF_OUT(); + return 0; +} +// LCOV_EXCL_STOP + +/********************************************************* + * TOUCH + *********************************************************/ +int tskm_pf_touch(char* path) { + TSKM_PORTPF_IN(); + int fd; + fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0666); + if (fd < 0) { + TSKM_ASSERT_ERRNO(0); + goto ERROR; + } + + TSKM_ASSERT_ERRNO(close(fd) == 0); + TSKM_PORTPF_OUT(); + return 0; + ERROR: + return -1; +} + +/********************************************************* + * Touch + *********************************************************/ +int tskm_pf_mkTouchFileName(pid_t pid, char name[32]) { + TSKM_PORTPF_IN(); + + sprintf(name, "/tmp/tskm_touch%d", pid); // NOLINT (runtime/printf) + + TSKM_PORTPF_OUT(); + return 0; +} + +/********************************************************* + * Read file + *********************************************************/ +static ssize_t readFile(const char* filePath, void* l_buf, ssize_t bufSize) { + int fd = -1; + ssize_t readSize, totalReadSize = 0; + char *p_buf = (char*) l_buf; // NOLINT (readability/casting) + fd = open(filePath, O_RDONLY); + if (fd == -1) { + TSKM_ASSERT_ERRNO(0); + goto ERROR; + } + + do { + readSize = read(fd, p_buf, bufSize); + if (readSize == -1) { + if (errno == EINTR) { + continue; + } else { + TSKM_ASSERT_ERRNO(0); + goto ERROR; + } + } else if (readSize == 0) { + break; + } + + p_buf += readSize; + bufSize -= readSize; + totalReadSize += readSize; + } while (bufSize > 0); + + ERROR: if (fd != -1) { + close(fd); + } + + return totalReadSize; +} + +/********************************************************* + * Write to file + *********************************************************/ +static ssize_t writeFile(const char *filePath, const void* l_buf, + ssize_t bufSize) { + int ret = -1; + int fd = -1; + + const char *p_buf = (const char*) l_buf; + + ssize_t writeSize, totalWriteSize = 0; + + fd = open(filePath, O_RDWR | O_TRUNC | O_CREAT, S_IRWXU); + if (fd == -1) { // LCOV_EXCL_BR_LINE 5: Error branching of the standard-function open() + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + TSKM_ASSERT_ERRNO(0); // LCOV_EXCL_LINE 5: Error branching of the standard-function open() + goto ERROR; // LCOV_EXCL_LINE 5: Error branching of the standard-function open() + } + + do { + writeSize = write(fd, p_buf, bufSize); + if (writeSize == -1) { // LCOV_EXCL_BR_LINE 5: Error branching of the standard-function write() + // LCOV_EXCL_START 5: Error branching of the standard-function write() + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + if (errno == EINTR) { + continue; + } else { + TSKM_ASSERT_ERRNO(0); + goto ERROR; + } + // LCOV_EXCL_STOP + } else if (writeSize == 0) { // LCOV_EXCL_BR_LINE 5: Error branching of the standard-function write() + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + break; // LCOV_EXCL_LINE 5: Error branching of the standard-function write() + } + p_buf += writeSize; + bufSize -= writeSize; + totalWriteSize += writeSize; + } while (bufSize > 0); // LCOV_EXCL_BR_LINE 5: Error branching of the standard-function write() + + ret = fsync(fd); + if (ret == -1) { // LCOV_EXCL_BR_LINE 5: Error branching of the standard-function fsync() + // LCOV_EXCL_START 5: Error branching of the standard-function fsync() + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + TSKM_ASSERT_ERRNO(0); + goto ERROR; + // LCOV_EXCL_STOP + } + + ERROR: if (fd != -1) { // LCOV_EXCL_BR_LINE 5: Error branching of the standard-function open() + close(fd); + } + + return totalWriteSize; +} + +/********************************************************* + * Checksum calculation + *********************************************************/ +static uint32_t calcCheckSum(const void* p_buf, size_t bufSize) { + int ii; + int blockNum; + uint32_t sum = 0; + uint32_t *p_calcBuf = (uint32_t*) p_buf; // NOLINT (readability/casting) + + blockNum = static_cast(bufSize) / static_cast(sizeof(uint32_t)); + + for (ii = 0; ii < blockNum; ii++) { + sum += p_calcBuf[ii]; + } + + return sum; +} + +/********************************************************* + * Checking files + *********************************************************/ +static TSKM_BOOL_t checkFile(const char *filePath) { // LCOV_EXCL_START 6: Because the condition cannot be set + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + uint32_t checkSum; + struct stat st; + ssize_t readSize; + TSKM_NV_INFO_t nvInfo; + TSKM_BOOL_t isFileOk = TSKM_FALSE; + + if (stat(filePath, &st) != 0) { + goto ERROR; + } + + readSize = readFile(filePath, &nvInfo, sizeof(TSKM_NV_INFO_t)); + if (readSize != sizeof(TSKM_NV_INFO_t)) { + TSKM_ASSERT(0); + goto ERROR; + } + + checkSum = calcCheckSum(&nvInfo, offsetof(TSKM_NV_INFO_t, footer.checkSum)); + + if (checkSum != nvInfo.footer.checkSum) { + TSKM_ASSERT(0); + goto ERROR; + } + + if (strncmp(nvInfo.header.version, TSKM_NV_STRUCT_VERSION, + sizeof(TSKM_NV_STRUCT_VERSION)) != 0) { + TSKM_ASSERT(0); + goto ERROR; + } + + isFileOk = TSKM_TRUE; + ERROR: return isFileOk; +} +// LCOV_EXCL_STOP +/********************************************************* + * Non-volatile file initialization (Including checksum write) + *********************************************************/ +static int initNvFile() { + int ii; + ssize_t writeSize; + TSKM_NV_INFO_t nvInfo; + + TSKM_STATIC_ASSERT(sizeof(TSKM_NV_INFO_t) == TSKM_NV_SIZE_ALL); + TSKM_STATIC_ASSERT( + offsetof(TSKM_NV_INFO_t, footer.checkSum) % sizeof(uint32_t) == 0); + + memset(&nvInfo, 0, sizeof(TSKM_NV_INFO_t)); + sprintf(nvInfo.header.version, TSKM_NV_STRUCT_VERSION); // NOLINT (readability/casting) + nvInfo.body.rsvSvcNum = 0; + for (ii = 0; ii < TSKM_SVC_RESERVE_MAX; ii++) { + nvInfo.body.rsvSvcs[ii] = TSKM_SVCID_NONE; + } + nvInfo.footer.checkSum = calcCheckSum( + &nvInfo, offsetof(TSKM_NV_INFO_t, footer.checkSum)); + + writeSize = writeFile(TSKM_TMP_NV_INFO_FILEPATH, &nvInfo, + sizeof(TSKM_NV_INFO_t)); + if (writeSize != sizeof(TSKM_NV_INFO_t)) { // LCOV_EXCL_BR_LINE 6: writeSize must be the size of TSKM_NV_INFO_t + // LCOV_EXCL_START 6: writeSize must be the size of TSKM_NV_INFO_t + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + TSKM_ASSERT(0); + goto ERROR; + // LCOV_EXCL_STOP + } + + return 0; + ERROR: return -1; +} + +/********************************************************* + * Non-volatile file initialization + *********************************************************/ +int tskm_pf_nvFileInit(HANDLE hApp) { + int ret = -1; + struct stat st; + EFrameworkunifiedStatus l_eStatus; + + if (stat(TSKM_TMP_TSKM_DIRECTORY, &st) != 0) { // LCOV_EXCL_BR_LINE 5:Standard C function return value + // LCOV_EXCL_START 5:Standard C function return value + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + ret = mkdir(TSKM_TMP_TSKM_DIRECTORY, S_IRWXU); + if (ret == -1) { + TSKM_ASSERT_ERRNO(0); + goto ERROR; + } + // LCOV_EXCL_STOP + } + + l_eStatus = FrameworkunifiedNPRegisterPersistentFile(hApp, TSKM_NPP_NV_FILE_TAG); + if (eFrameworkunifiedStatusOK != l_eStatus) { // LCOV_EXCL_BR_LINE 6: For processing initializing process + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + TSKM_ASSERT(0); // LCOV_EXCL_LINE 6: For processing initializing process + goto ERROR; // LCOV_EXCL_LINE 6: For processing initializing process + } + + l_eStatus = FrameworkunifiedNPLoadPersistentFile(hApp, TSKM_TMP_NV_INFO_FILEPATH, TSKM_NPP_NV_FILE_TAG); + if (eFrameworkunifiedStatusOK != l_eStatus) { // LCOV_EXCL_BR_LINE 6: For processing initializing process + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + TSKM_ASSERT(0); // LCOV_EXCL_LINE 6: For processing initializing process + goto ERROR; // LCOV_EXCL_LINE 6: For processing initializing process + } + + return 0; + ERROR: return -1; +} + +/********************************************************* + * Non-volatile file read + *********************************************************/ +int tskm_pf_nvFileRead(HANDLE hApp, TSKM_NV_INFO_t* p_nvInfo) { + EFrameworkunifiedStatus l_eStatus = eFrameworkunifiedStatusOK; + NC_LoadPersistedAck l_tMsgAck; + ssize_t readSize; + TSKM_BOOL_t isTmpFileOk = TSKM_FALSE; + + if (sizeof(l_tMsgAck) != FrameworkunifiedGetMsgLength(hApp)) { + TSKM_ASSERT(0); + goto ERROR; + } else if (eFrameworkunifiedStatusOK != (l_eStatus = FrameworkunifiedGetMsgDataOfSize(hApp, &l_tMsgAck, sizeof(l_tMsgAck)))) { // LCOV_EXCL_BR_LINE 4: NSFW error case // NOLINT[whitespace/line_length] + // LCOV_EXCL_START 4: NSFW error case + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + TSKM_ASSERT(0); + goto ERROR; + // LCOV_EXCL_STOP + } + + if ((strncmp(l_tMsgAck.cTag, TSKM_NPP_NV_FILE_TAG, sizeof(TSKM_NPP_NV_FILE_TAG)) == 0) + && (eFrameworkunifiedStatusOK == l_tMsgAck.eStatus)) { + if (checkFile(TSKM_TMP_NV_INFO_FILEPATH) == TSKM_TRUE) { + isTmpFileOk = TSKM_TRUE; + } + } + + if (isTmpFileOk == TSKM_FALSE) { + int ret; + + ret = initNvFile(); + if (ret == -1) { // LCOV_EXCL_BR_LINE 6: must return ok + // LCOV_EXCL_START 6: must return ok + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + TSKM_ASSERT(0); + goto ERROR; + // LCOV_EXCL_STOP + } + } + + readSize = readFile(TSKM_TMP_NV_INFO_FILEPATH, p_nvInfo, + sizeof(TSKM_NV_INFO_t)); + if (readSize != sizeof(TSKM_NV_INFO_t)) { // LCOV_EXCL_BR_LINE 6: readSize must be the size of TSKM_NV_INFO_t + // LCOV_EXCL_START 6: readSize must be the size of TSKM_NV_INFO_t + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + TSKM_ASSERT(0); + goto ERROR; + // LCOV_EXCL_STOP + } + + l_eStatus = FrameworkunifiedNPReleasePersistentFile(hApp, eFrameworkunifiedPersistOnShutdown, TSKM_NPP_NV_FILE_TAG, TSKM_TMP_NV_INFO_FILEPATH); + if (eFrameworkunifiedStatusOK != l_eStatus) { + TSKM_ASSERT(0); + } + + return 0; + ERROR: return -1; +} + +/********************************************************* + * Write non-volatile file (Including checksum) + *********************************************************/ +int tskm_pf_nvFileWrite(const TSKM_NV_INFO_t* p_nvInfo) { + ssize_t writeSize; + TSKM_NV_INFO_t nvInfo; + + memcpy(&nvInfo, p_nvInfo, sizeof(TSKM_NV_INFO_t)); + + nvInfo.footer.checkSum = calcCheckSum( + &nvInfo, offsetof(TSKM_NV_INFO_t, footer.checkSum)); + + writeSize = writeFile(TSKM_TMP_NV_INFO_FILEPATH, &nvInfo, + sizeof(TSKM_NV_INFO_t)); + if (writeSize != sizeof(TSKM_NV_INFO_t)) { // LCOV_EXCL_BR_LINE 6: writeSize must be the size of TSKM_NV_INFO_t + // LCOV_EXCL_START 6: writeSize must be the size of TSKM_NV_INFO_t + AGL_ASSERT_NOT_TESTED(); // LCOV_EXCL_LINE 200: test assert + TSKM_ASSERT(0); + return -1; + // LCOV_EXCL_STOP + } + return 0; +} // LCOV_EXCL_BR_LINE 10: Final line -- cgit 1.2.3-korg