169570cc8Sopenharmony_ci/* 269570cc8Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd. 369570cc8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 469570cc8Sopenharmony_ci * you may not use this file except in compliance with the License. 569570cc8Sopenharmony_ci * You may obtain a copy of the License at 669570cc8Sopenharmony_ci * 769570cc8Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 869570cc8Sopenharmony_ci * 969570cc8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1069570cc8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1169570cc8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1269570cc8Sopenharmony_ci * See the License for the specific language governing permissions and 1369570cc8Sopenharmony_ci * limitations under the License. 1469570cc8Sopenharmony_ci */ 1569570cc8Sopenharmony_ci 1669570cc8Sopenharmony_ci#include "appspawn_client.h" 1769570cc8Sopenharmony_ci 1869570cc8Sopenharmony_ci#include <errno.h> 1969570cc8Sopenharmony_ci#include <fcntl.h> 2069570cc8Sopenharmony_ci#include <pthread.h> 2169570cc8Sopenharmony_ci#include <string.h> 2269570cc8Sopenharmony_ci#include <unistd.h> 2369570cc8Sopenharmony_ci 2469570cc8Sopenharmony_ci#include <linux/in.h> 2569570cc8Sopenharmony_ci#include <linux/socket.h> 2669570cc8Sopenharmony_ci#include <linux/tcp.h> 2769570cc8Sopenharmony_ci#include <sys/socket.h> 2869570cc8Sopenharmony_ci#include <sys/time.h> 2969570cc8Sopenharmony_ci#include <sys/types.h> 3069570cc8Sopenharmony_ci#include <sys/un.h> 3169570cc8Sopenharmony_ci 3269570cc8Sopenharmony_ci#include "appspawn_mount_permission.h" 3369570cc8Sopenharmony_ci#include "appspawn_hook.h" 3469570cc8Sopenharmony_ci#include "appspawn_utils.h" 3569570cc8Sopenharmony_ci#include "parameter.h" 3669570cc8Sopenharmony_ci#include "securec.h" 3769570cc8Sopenharmony_ci 3869570cc8Sopenharmony_cistatic pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER; 3969570cc8Sopenharmony_cistatic AppSpawnReqMsgMgr *g_clientInstance[CLIENT_MAX] = {NULL}; 4069570cc8Sopenharmony_ci 4169570cc8Sopenharmony_cistatic uint32_t GetDefaultTimeout(uint32_t def) 4269570cc8Sopenharmony_ci{ 4369570cc8Sopenharmony_ci uint32_t value = def; 4469570cc8Sopenharmony_ci char data[32] = {}; // 32 length 4569570cc8Sopenharmony_ci int ret = GetParameter("persist.appspawn.reqMgr.timeout", "0", data, sizeof(data)); 4669570cc8Sopenharmony_ci if (ret > 0 && strcmp(data, "0") != 0) { 4769570cc8Sopenharmony_ci errno = 0; 4869570cc8Sopenharmony_ci value = (uint32_t)atoi(data); 4969570cc8Sopenharmony_ci return (errno != 0) ? def : value; 5069570cc8Sopenharmony_ci } 5169570cc8Sopenharmony_ci return value; 5269570cc8Sopenharmony_ci} 5369570cc8Sopenharmony_ci 5469570cc8Sopenharmony_cistatic int InitClientInstance(AppSpawnClientType type) 5569570cc8Sopenharmony_ci{ 5669570cc8Sopenharmony_ci pthread_mutex_lock(&g_mutex); 5769570cc8Sopenharmony_ci if (g_clientInstance[type] != NULL) { 5869570cc8Sopenharmony_ci pthread_mutex_unlock(&g_mutex); 5969570cc8Sopenharmony_ci return 0; 6069570cc8Sopenharmony_ci } 6169570cc8Sopenharmony_ci AppSpawnReqMsgMgr *clientInstance = malloc(sizeof(AppSpawnReqMsgMgr) + RECV_BLOCK_LEN); 6269570cc8Sopenharmony_ci if (clientInstance == NULL) { 6369570cc8Sopenharmony_ci pthread_mutex_unlock(&g_mutex); 6469570cc8Sopenharmony_ci return APPSPAWN_SYSTEM_ERROR; 6569570cc8Sopenharmony_ci } 6669570cc8Sopenharmony_ci // init 6769570cc8Sopenharmony_ci clientInstance->type = type; 6869570cc8Sopenharmony_ci clientInstance->msgNextId = 1; 6969570cc8Sopenharmony_ci clientInstance->timeout = GetDefaultTimeout(TIMEOUT_DEF); 7069570cc8Sopenharmony_ci clientInstance->maxRetryCount = MAX_RETRY_SEND_COUNT; 7169570cc8Sopenharmony_ci clientInstance->socketId = -1; 7269570cc8Sopenharmony_ci pthread_mutex_init(&clientInstance->mutex, NULL); 7369570cc8Sopenharmony_ci // init recvBlock 7469570cc8Sopenharmony_ci OH_ListInit(&clientInstance->recvBlock.node); 7569570cc8Sopenharmony_ci clientInstance->recvBlock.blockSize = RECV_BLOCK_LEN; 7669570cc8Sopenharmony_ci clientInstance->recvBlock.currentIndex = 0; 7769570cc8Sopenharmony_ci g_clientInstance[type] = clientInstance; 7869570cc8Sopenharmony_ci pthread_mutex_unlock(&g_mutex); 7969570cc8Sopenharmony_ci return 0; 8069570cc8Sopenharmony_ci} 8169570cc8Sopenharmony_ci 8269570cc8Sopenharmony_ciAPPSPAWN_STATIC void CloseClientSocket(int socketId) 8369570cc8Sopenharmony_ci{ 8469570cc8Sopenharmony_ci APPSPAWN_LOGV("Closed socket with fd %{public}d", socketId); 8569570cc8Sopenharmony_ci if (socketId >= 0) { 8669570cc8Sopenharmony_ci int flag = 0; 8769570cc8Sopenharmony_ci setsockopt(socketId, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int)); 8869570cc8Sopenharmony_ci close(socketId); 8969570cc8Sopenharmony_ci } 9069570cc8Sopenharmony_ci} 9169570cc8Sopenharmony_ci 9269570cc8Sopenharmony_ciAPPSPAWN_STATIC int CreateClientSocket(uint32_t type, uint32_t timeout) 9369570cc8Sopenharmony_ci{ 9469570cc8Sopenharmony_ci const char *socketName; 9569570cc8Sopenharmony_ci 9669570cc8Sopenharmony_ci switch (type) { 9769570cc8Sopenharmony_ci case CLIENT_FOR_APPSPAWN: 9869570cc8Sopenharmony_ci socketName = APPSPAWN_SOCKET_NAME; 9969570cc8Sopenharmony_ci break; 10069570cc8Sopenharmony_ci case CLIENT_FOR_CJAPPSPAWN: 10169570cc8Sopenharmony_ci socketName = CJAPPSPAWN_SOCKET_NAME; 10269570cc8Sopenharmony_ci break; 10369570cc8Sopenharmony_ci case CLIENT_FOR_NATIVESPAWN: 10469570cc8Sopenharmony_ci socketName = NATIVESPAWN_SOCKET_NAME; 10569570cc8Sopenharmony_ci break; 10669570cc8Sopenharmony_ci default: 10769570cc8Sopenharmony_ci socketName = NWEBSPAWN_SOCKET_NAME; 10869570cc8Sopenharmony_ci break; 10969570cc8Sopenharmony_ci } 11069570cc8Sopenharmony_ci 11169570cc8Sopenharmony_ci int socketFd = socket(AF_UNIX, SOCK_STREAM, 0); // SOCK_SEQPACKET 11269570cc8Sopenharmony_ci APPSPAWN_CHECK(socketFd >= 0, return -1, 11369570cc8Sopenharmony_ci "Socket socket fd: %{public}s error: %{public}d", socketName, errno); 11469570cc8Sopenharmony_ci int ret = 0; 11569570cc8Sopenharmony_ci do { 11669570cc8Sopenharmony_ci int flag = 1; 11769570cc8Sopenharmony_ci ret = setsockopt(socketFd, IPPROTO_TCP, TCP_NODELAY, (char *)&flag, sizeof(int)); 11869570cc8Sopenharmony_ci flag = 1; 11969570cc8Sopenharmony_ci ret = setsockopt(socketFd, SOL_SOCKET, SO_PASSCRED, &flag, sizeof(flag)); 12069570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, break, "Set opt SO_PASSCRED name: %{public}s error: %{public}d", socketName, errno); 12169570cc8Sopenharmony_ci 12269570cc8Sopenharmony_ci struct timeval timeoutVal = {timeout, 0}; 12369570cc8Sopenharmony_ci ret = setsockopt(socketFd, SOL_SOCKET, SO_SNDTIMEO, &timeoutVal, sizeof(timeoutVal)); 12469570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, break, "Set opt SO_SNDTIMEO name: %{public}s error: %{public}d", socketName, errno); 12569570cc8Sopenharmony_ci ret = setsockopt(socketFd, SOL_SOCKET, SO_RCVTIMEO, &timeoutVal, sizeof(timeoutVal)); 12669570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, break, "Set opt SO_RCVTIMEO name: %{public}s error: %{public}d", socketName, errno); 12769570cc8Sopenharmony_ci 12869570cc8Sopenharmony_ci ret = APPSPAWN_SYSTEM_ERROR; 12969570cc8Sopenharmony_ci struct sockaddr_un addr; 13069570cc8Sopenharmony_ci socklen_t pathSize = sizeof(addr.sun_path); 13169570cc8Sopenharmony_ci int pathLen = snprintf_s(addr.sun_path, pathSize, (pathSize - 1), "%s%s", APPSPAWN_SOCKET_DIR, socketName); 13269570cc8Sopenharmony_ci APPSPAWN_CHECK(pathLen > 0, break, "Format path %{public}s error: %{public}d", socketName, errno); 13369570cc8Sopenharmony_ci addr.sun_family = AF_LOCAL; 13469570cc8Sopenharmony_ci socklen_t socketAddrLen = (socklen_t)(offsetof(struct sockaddr_un, sun_path) + (socklen_t)pathLen + 1); 13569570cc8Sopenharmony_ci ret = connect(socketFd, (struct sockaddr *)(&addr), socketAddrLen); 13669570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, break, 13769570cc8Sopenharmony_ci "Failed to connect %{public}s error: %{public}d", addr.sun_path, errno); 13869570cc8Sopenharmony_ci APPSPAWN_LOGI("Create socket success %{public}s socketFd: %{public}d", addr.sun_path, socketFd); 13969570cc8Sopenharmony_ci return socketFd; 14069570cc8Sopenharmony_ci } while (0); 14169570cc8Sopenharmony_ci CloseClientSocket(socketFd); 14269570cc8Sopenharmony_ci return -1; 14369570cc8Sopenharmony_ci} 14469570cc8Sopenharmony_ci 14569570cc8Sopenharmony_ciAPPSPAWN_STATIC int UpdateSocketTimeout(uint32_t timeout, int socketFd) 14669570cc8Sopenharmony_ci{ 14769570cc8Sopenharmony_ci struct timeval timeoutVal = {timeout, 0}; 14869570cc8Sopenharmony_ci int ret = setsockopt(socketFd, SOL_SOCKET, SO_SNDTIMEO, &timeoutVal, sizeof(timeoutVal)); 14969570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "Set opt SO_SNDTIMEO error: %{public}d", errno); 15069570cc8Sopenharmony_ci ret = setsockopt(socketFd, SOL_SOCKET, SO_RCVTIMEO, &timeoutVal, sizeof(timeoutVal)); 15169570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "Set opt SO_RCVTIMEO error: %{public}d", errno); 15269570cc8Sopenharmony_ci return ret; 15369570cc8Sopenharmony_ci} 15469570cc8Sopenharmony_ci 15569570cc8Sopenharmony_cistatic int ReadMessage(int socketFd, uint32_t sendMsgId, uint8_t *buf, int len, AppSpawnResult *result) 15669570cc8Sopenharmony_ci{ 15769570cc8Sopenharmony_ci ssize_t rLen = TEMP_FAILURE_RETRY(read(socketFd, buf, len)); 15869570cc8Sopenharmony_ci APPSPAWN_CHECK(rLen >= 0, return APPSPAWN_TIMEOUT, 15969570cc8Sopenharmony_ci "Read message from fd %{public}d rLen %{public}zd errno: %{public}d", socketFd, rLen, errno); 16069570cc8Sopenharmony_ci if ((size_t)rLen >= sizeof(AppSpawnResponseMsg)) { 16169570cc8Sopenharmony_ci AppSpawnResponseMsg *msg = (AppSpawnResponseMsg *)(buf); 16269570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_LOG(sendMsgId == msg->msgHdr.msgId, 16369570cc8Sopenharmony_ci "Invalid msg recvd %{public}u %{public}u", sendMsgId, msg->msgHdr.msgId); 16469570cc8Sopenharmony_ci return memcpy_s(result, sizeof(AppSpawnResult), &msg->result, sizeof(msg->result)); 16569570cc8Sopenharmony_ci } 16669570cc8Sopenharmony_ci return APPSPAWN_TIMEOUT; 16769570cc8Sopenharmony_ci} 16869570cc8Sopenharmony_ci 16969570cc8Sopenharmony_cistatic int WriteMessage(int socketFd, const uint8_t *buf, ssize_t len, int *fds, int *fdCount) 17069570cc8Sopenharmony_ci{ 17169570cc8Sopenharmony_ci ssize_t written = 0; 17269570cc8Sopenharmony_ci ssize_t remain = len; 17369570cc8Sopenharmony_ci const uint8_t *offset = buf; 17469570cc8Sopenharmony_ci struct iovec iov = { 17569570cc8Sopenharmony_ci .iov_base = (void *) offset, 17669570cc8Sopenharmony_ci .iov_len = len, 17769570cc8Sopenharmony_ci }; 17869570cc8Sopenharmony_ci struct msghdr msg = { 17969570cc8Sopenharmony_ci .msg_iov = &iov, 18069570cc8Sopenharmony_ci .msg_iovlen = 1, 18169570cc8Sopenharmony_ci }; 18269570cc8Sopenharmony_ci char *ctrlBuffer = NULL; 18369570cc8Sopenharmony_ci if (fdCount != NULL && fds != NULL && *fdCount > 0) { 18469570cc8Sopenharmony_ci msg.msg_controllen = CMSG_SPACE(*fdCount * sizeof(int)); 18569570cc8Sopenharmony_ci ctrlBuffer = (char *) malloc(msg.msg_controllen); 18669570cc8Sopenharmony_ci APPSPAWN_CHECK(ctrlBuffer != NULL, return -1, 18769570cc8Sopenharmony_ci "WriteMessage fail to alloc memory for msg_control %{public}d %{public}d", msg.msg_controllen, errno); 18869570cc8Sopenharmony_ci msg.msg_control = ctrlBuffer; 18969570cc8Sopenharmony_ci struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg); 19069570cc8Sopenharmony_ci APPSPAWN_CHECK(cmsg != NULL, free(ctrlBuffer); 19169570cc8Sopenharmony_ci return -1, "WriteMessage fail to get CMSG_FIRSTHDR %{public}d", errno); 19269570cc8Sopenharmony_ci cmsg->cmsg_len = CMSG_LEN(*fdCount * sizeof(int)); 19369570cc8Sopenharmony_ci cmsg->cmsg_type = SCM_RIGHTS; 19469570cc8Sopenharmony_ci cmsg->cmsg_level = SOL_SOCKET; 19569570cc8Sopenharmony_ci int ret = memcpy_s(CMSG_DATA(cmsg), cmsg->cmsg_len, fds, *fdCount * sizeof(int)); 19669570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, free(ctrlBuffer); 19769570cc8Sopenharmony_ci return -1, "WriteMessage fail to memcpy_s fd %{public}d", errno); 19869570cc8Sopenharmony_ci APPSPAWN_LOGV("build fd info count %{public}d", *fdCount); 19969570cc8Sopenharmony_ci } 20069570cc8Sopenharmony_ci for (ssize_t wLen = 0; remain > 0; offset += wLen, remain -= wLen, written += wLen) { 20169570cc8Sopenharmony_ci errno = 0; 20269570cc8Sopenharmony_ci wLen = sendmsg(socketFd, &msg, MSG_NOSIGNAL); 20369570cc8Sopenharmony_ci APPSPAWN_LOGV("Write msg errno: %{public}d %{public}zd", errno, wLen); 20469570cc8Sopenharmony_ci APPSPAWN_CHECK((wLen > 0) || (errno == EINTR), free(ctrlBuffer); 20569570cc8Sopenharmony_ci return -errno, 20669570cc8Sopenharmony_ci "Failed to write message to fd %{public}d, wLen %{public}zd errno: %{public}d", socketFd, wLen, errno); 20769570cc8Sopenharmony_ci } 20869570cc8Sopenharmony_ci free(ctrlBuffer); 20969570cc8Sopenharmony_ci return written == len ? 0 : -EFAULT; 21069570cc8Sopenharmony_ci} 21169570cc8Sopenharmony_ci 21269570cc8Sopenharmony_cistatic int HandleMsgSend(AppSpawnReqMsgMgr *reqMgr, int socketId, AppSpawnReqMsgNode *reqNode) 21369570cc8Sopenharmony_ci{ 21469570cc8Sopenharmony_ci APPSPAWN_LOGV("HandleMsgSend reqId: %{public}u msgId: %{public}d", reqNode->reqId, reqNode->msg->msgId); 21569570cc8Sopenharmony_ci ListNode *sendNode = reqNode->msgBlocks.next; 21669570cc8Sopenharmony_ci uint32_t currentIndex = 0; 21769570cc8Sopenharmony_ci bool sendFd = true; 21869570cc8Sopenharmony_ci while (sendNode != NULL && sendNode != &reqNode->msgBlocks) { 21969570cc8Sopenharmony_ci AppSpawnMsgBlock *sendBlock = (AppSpawnMsgBlock *)ListEntry(sendNode, AppSpawnMsgBlock, node); 22069570cc8Sopenharmony_ci int ret = WriteMessage(socketId, sendBlock->buffer, sendBlock->currentIndex, 22169570cc8Sopenharmony_ci sendFd ? reqNode->fds : NULL, 22269570cc8Sopenharmony_ci sendFd ? &reqNode->fdCount : NULL); 22369570cc8Sopenharmony_ci currentIndex += sendBlock->currentIndex; 22469570cc8Sopenharmony_ci APPSPAWN_LOGV("Write msg ret: %{public}d msgId: %{public}u %{public}u %{public}u", 22569570cc8Sopenharmony_ci ret, reqNode->msg->msgId, reqNode->msg->msgLen, currentIndex); 22669570cc8Sopenharmony_ci if (ret == 0) { 22769570cc8Sopenharmony_ci sendFd = false; 22869570cc8Sopenharmony_ci sendNode = sendNode->next; 22969570cc8Sopenharmony_ci continue; 23069570cc8Sopenharmony_ci } 23169570cc8Sopenharmony_ci APPSPAWN_LOGE("Send msg fail reqId: %{public}u msgId: %{public}d ret: %{public}d", 23269570cc8Sopenharmony_ci reqNode->reqId, reqNode->msg->msgId, ret); 23369570cc8Sopenharmony_ci return ret; 23469570cc8Sopenharmony_ci } 23569570cc8Sopenharmony_ci return 0; 23669570cc8Sopenharmony_ci} 23769570cc8Sopenharmony_ci 23869570cc8Sopenharmony_ciAPPSPAWN_STATIC void TryCreateSocket(AppSpawnReqMsgMgr *reqMgr) 23969570cc8Sopenharmony_ci{ 24069570cc8Sopenharmony_ci uint32_t retryCount = 1; 24169570cc8Sopenharmony_ci while (retryCount <= reqMgr->maxRetryCount) { 24269570cc8Sopenharmony_ci if (reqMgr->socketId < 0) { 24369570cc8Sopenharmony_ci reqMgr->socketId = CreateClientSocket(reqMgr->type, reqMgr->timeout); 24469570cc8Sopenharmony_ci } 24569570cc8Sopenharmony_ci if (reqMgr->socketId < 0) { 24669570cc8Sopenharmony_ci APPSPAWN_LOGV("Failed to create socket, try again"); 24769570cc8Sopenharmony_ci usleep(RETRY_TIME); 24869570cc8Sopenharmony_ci retryCount++; 24969570cc8Sopenharmony_ci continue; 25069570cc8Sopenharmony_ci } 25169570cc8Sopenharmony_ci break; 25269570cc8Sopenharmony_ci } 25369570cc8Sopenharmony_ci} 25469570cc8Sopenharmony_ci 25569570cc8Sopenharmony_cistatic int ClientSendMsg(AppSpawnReqMsgMgr *reqMgr, AppSpawnReqMsgNode *reqNode, AppSpawnResult *result) 25669570cc8Sopenharmony_ci{ 25769570cc8Sopenharmony_ci uint32_t retryCount = 1; 25869570cc8Sopenharmony_ci int isColdRun = reqNode->isAsan; 25969570cc8Sopenharmony_ci while (retryCount <= reqMgr->maxRetryCount) { 26069570cc8Sopenharmony_ci if (reqMgr->socketId < 0) { // try create socket 26169570cc8Sopenharmony_ci TryCreateSocket(reqMgr); 26269570cc8Sopenharmony_ci if (reqMgr->socketId < 0) { 26369570cc8Sopenharmony_ci usleep(RETRY_TIME); 26469570cc8Sopenharmony_ci retryCount++; 26569570cc8Sopenharmony_ci continue; 26669570cc8Sopenharmony_ci } 26769570cc8Sopenharmony_ci } 26869570cc8Sopenharmony_ci if (isColdRun && reqMgr->timeout < ASAN_TIMEOUT) { 26969570cc8Sopenharmony_ci UpdateSocketTimeout(ASAN_TIMEOUT, reqMgr->socketId); 27069570cc8Sopenharmony_ci } 27169570cc8Sopenharmony_ci 27269570cc8Sopenharmony_ci if (reqNode->msg->msgId == 0) { 27369570cc8Sopenharmony_ci reqNode->msg->msgId = reqMgr->msgNextId++; 27469570cc8Sopenharmony_ci } 27569570cc8Sopenharmony_ci int ret = HandleMsgSend(reqMgr, reqMgr->socketId, reqNode); 27669570cc8Sopenharmony_ci if (ret == 0) { 27769570cc8Sopenharmony_ci ret = ReadMessage(reqMgr->socketId, reqNode->msg->msgId, 27869570cc8Sopenharmony_ci reqMgr->recvBlock.buffer, reqMgr->recvBlock.blockSize, result); 27969570cc8Sopenharmony_ci } 28069570cc8Sopenharmony_ci if (ret == 0) { 28169570cc8Sopenharmony_ci if (isColdRun && reqMgr->timeout < ASAN_TIMEOUT) { 28269570cc8Sopenharmony_ci UpdateSocketTimeout(reqMgr->timeout, reqMgr->socketId); 28369570cc8Sopenharmony_ci } 28469570cc8Sopenharmony_ci return 0; 28569570cc8Sopenharmony_ci } 28669570cc8Sopenharmony_ci // retry 28769570cc8Sopenharmony_ci CloseClientSocket(reqMgr->socketId); 28869570cc8Sopenharmony_ci reqMgr->socketId = -1; 28969570cc8Sopenharmony_ci reqMgr->msgNextId = 1; 29069570cc8Sopenharmony_ci reqNode->msg->msgId = 0; 29169570cc8Sopenharmony_ci usleep(RETRY_TIME); 29269570cc8Sopenharmony_ci retryCount++; 29369570cc8Sopenharmony_ci } 29469570cc8Sopenharmony_ci return APPSPAWN_TIMEOUT; 29569570cc8Sopenharmony_ci} 29669570cc8Sopenharmony_ci 29769570cc8Sopenharmony_ciint AppSpawnClientInit(const char *serviceName, AppSpawnClientHandle *handle) 29869570cc8Sopenharmony_ci{ 29969570cc8Sopenharmony_ci APPSPAWN_CHECK(serviceName != NULL, return APPSPAWN_ARG_INVALID, "Invalid service name"); 30069570cc8Sopenharmony_ci APPSPAWN_CHECK(handle != NULL, return APPSPAWN_ARG_INVALID, "Invalid handle for %{public}s", serviceName); 30169570cc8Sopenharmony_ci APPSPAWN_LOGV("AppSpawnClientInit serviceName %{public}s", serviceName); 30269570cc8Sopenharmony_ci AppSpawnClientType type = CLIENT_FOR_APPSPAWN; 30369570cc8Sopenharmony_ci if (strcmp(serviceName, CJAPPSPAWN_SERVER_NAME) == 0) { 30469570cc8Sopenharmony_ci type = CLIENT_FOR_CJAPPSPAWN; 30569570cc8Sopenharmony_ci } else if (strcmp(serviceName, NWEBSPAWN_SERVER_NAME) == 0 || strstr(serviceName, NWEBSPAWN_SOCKET_NAME) != NULL) { 30669570cc8Sopenharmony_ci type = CLIENT_FOR_NWEBSPAWN; 30769570cc8Sopenharmony_ci } else if (strcmp(serviceName, NATIVESPAWN_SERVER_NAME) == 0 || 30869570cc8Sopenharmony_ci strstr(serviceName, NATIVESPAWN_SOCKET_NAME) != NULL) { 30969570cc8Sopenharmony_ci type = CLIENT_FOR_NATIVESPAWN; 31069570cc8Sopenharmony_ci } 31169570cc8Sopenharmony_ci int ret = InitClientInstance(type); 31269570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return APPSPAWN_SYSTEM_ERROR, "Failed to create reqMgr"); 31369570cc8Sopenharmony_ci *handle = (AppSpawnClientHandle)g_clientInstance[type]; 31469570cc8Sopenharmony_ci return 0; 31569570cc8Sopenharmony_ci} 31669570cc8Sopenharmony_ci 31769570cc8Sopenharmony_ciint AppSpawnClientDestroy(AppSpawnClientHandle handle) 31869570cc8Sopenharmony_ci{ 31969570cc8Sopenharmony_ci AppSpawnReqMsgMgr *reqMgr = (AppSpawnReqMsgMgr *)handle; 32069570cc8Sopenharmony_ci APPSPAWN_CHECK(reqMgr != NULL, return APPSPAWN_SYSTEM_ERROR, "Invalid reqMgr"); 32169570cc8Sopenharmony_ci pthread_mutex_lock(&g_mutex); 32269570cc8Sopenharmony_ci if (reqMgr->type < sizeof(g_clientInstance) / sizeof(g_clientInstance[0])) { 32369570cc8Sopenharmony_ci g_clientInstance[reqMgr->type] = NULL; 32469570cc8Sopenharmony_ci } 32569570cc8Sopenharmony_ci pthread_mutex_unlock(&g_mutex); 32669570cc8Sopenharmony_ci pthread_mutex_destroy(&reqMgr->mutex); 32769570cc8Sopenharmony_ci if (reqMgr->socketId >= 0) { 32869570cc8Sopenharmony_ci CloseClientSocket(reqMgr->socketId); 32969570cc8Sopenharmony_ci reqMgr->socketId = -1; 33069570cc8Sopenharmony_ci } 33169570cc8Sopenharmony_ci free(reqMgr); 33269570cc8Sopenharmony_ci return 0; 33369570cc8Sopenharmony_ci} 33469570cc8Sopenharmony_ci 33569570cc8Sopenharmony_ciint AppSpawnClientSendMsg(AppSpawnClientHandle handle, AppSpawnReqMsgHandle reqHandle, AppSpawnResult *result) 33669570cc8Sopenharmony_ci{ 33769570cc8Sopenharmony_ci APPSPAWN_CHECK(result != NULL, AppSpawnReqMsgFree(reqHandle); 33869570cc8Sopenharmony_ci return APPSPAWN_ARG_INVALID, "Invalid result"); 33969570cc8Sopenharmony_ci result->result = APPSPAWN_ARG_INVALID; 34069570cc8Sopenharmony_ci result->pid = 0; 34169570cc8Sopenharmony_ci AppSpawnReqMsgMgr *reqMgr = (AppSpawnReqMsgMgr *)handle; 34269570cc8Sopenharmony_ci APPSPAWN_CHECK(reqMgr != NULL, AppSpawnReqMsgFree(reqHandle); 34369570cc8Sopenharmony_ci return APPSPAWN_ARG_INVALID, "Invalid reqMgr"); 34469570cc8Sopenharmony_ci AppSpawnReqMsgNode *reqNode = (AppSpawnReqMsgNode *)reqHandle; 34569570cc8Sopenharmony_ci APPSPAWN_CHECK(reqNode != NULL && reqNode->msg != NULL, AppSpawnReqMsgFree(reqHandle); 34669570cc8Sopenharmony_ci return APPSPAWN_ARG_INVALID, "Invalid msgReq"); 34769570cc8Sopenharmony_ci 34869570cc8Sopenharmony_ci APPSPAWN_LOGI("AppSpawnClientSendMsg reqId: %{public}u msgLen: %{public}u %{public}s", 34969570cc8Sopenharmony_ci reqNode->reqId, reqNode->msg->msgLen, reqNode->msg->processName); 35069570cc8Sopenharmony_ci pthread_mutex_lock(&reqMgr->mutex); 35169570cc8Sopenharmony_ci int ret = ClientSendMsg(reqMgr, reqNode, result); 35269570cc8Sopenharmony_ci if (ret != 0) { 35369570cc8Sopenharmony_ci result->result = ret; 35469570cc8Sopenharmony_ci } 35569570cc8Sopenharmony_ci pthread_mutex_unlock(&reqMgr->mutex); 35669570cc8Sopenharmony_ci APPSPAWN_LOGI("AppSpawnClientSendMsg reqId: %{public}u end result: 0x%{public}x pid: %{public}d", 35769570cc8Sopenharmony_ci reqNode->reqId, result->result, result->pid); 35869570cc8Sopenharmony_ci AppSpawnReqMsgFree(reqHandle); 35969570cc8Sopenharmony_ci return ret; 36069570cc8Sopenharmony_ci} 361