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 <cerrno> 1769570cc8Sopenharmony_ci#include <cstring> 1869570cc8Sopenharmony_ci#include <dlfcn.h> 1969570cc8Sopenharmony_ci#include <set> 2069570cc8Sopenharmony_ci#include <string> 2169570cc8Sopenharmony_ci#include <unistd.h> 2269570cc8Sopenharmony_ci#include <utility> 2369570cc8Sopenharmony_ci#include <vector> 2469570cc8Sopenharmony_ci 2569570cc8Sopenharmony_ci#include "appspawn_hook.h" 2669570cc8Sopenharmony_ci#include "appspawn_server.h" 2769570cc8Sopenharmony_ci#include "appspawn_service.h" 2869570cc8Sopenharmony_ci#include "appspawn_manager.h" 2969570cc8Sopenharmony_ci#include "appspawn_utils.h" 3069570cc8Sopenharmony_ci#include "parameters.h" 3169570cc8Sopenharmony_ci#ifndef APPSPAWN_TEST 3269570cc8Sopenharmony_ci#include "main_thread.h" 3369570cc8Sopenharmony_ci#endif 3469570cc8Sopenharmony_ci 3569570cc8Sopenharmony_ciAPPSPAWN_STATIC int BuildFdInfoMap(const AppSpawnMsgNode *message, std::map<std::string, int> &fdMap, int isColdRun) 3669570cc8Sopenharmony_ci{ 3769570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(message != NULL && message->buffer != NULL, return -1); 3869570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(message->tlvOffset != NULL, return -1); 3969570cc8Sopenharmony_ci int findFdIndex = 0; 4069570cc8Sopenharmony_ci AppSpawnMsgReceiverCtx recvCtx; 4169570cc8Sopenharmony_ci if (!isColdRun) { 4269570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(message->connection != NULL, return -1); 4369570cc8Sopenharmony_ci recvCtx = message->connection->receiverCtx; 4469570cc8Sopenharmony_ci if (recvCtx.fdCount <= 0) { 4569570cc8Sopenharmony_ci APPSPAWN_LOGI("no need to build fd info %{public}d, %{public}d", recvCtx.fds != NULL, recvCtx.fdCount); 4669570cc8Sopenharmony_ci return 0; 4769570cc8Sopenharmony_ci } 4869570cc8Sopenharmony_ci } 4969570cc8Sopenharmony_ci for (uint32_t index = TLV_MAX; index < (TLV_MAX + message->tlvCount); index++) { 5069570cc8Sopenharmony_ci if (message->tlvOffset[index] == INVALID_OFFSET) { 5169570cc8Sopenharmony_ci return -1; 5269570cc8Sopenharmony_ci } 5369570cc8Sopenharmony_ci uint8_t *data = message->buffer + message->tlvOffset[index]; 5469570cc8Sopenharmony_ci if (((AppSpawnTlv *)data)->tlvType != TLV_MAX) { 5569570cc8Sopenharmony_ci continue; 5669570cc8Sopenharmony_ci } 5769570cc8Sopenharmony_ci AppSpawnTlvExt *tlv = (AppSpawnTlvExt *)data; 5869570cc8Sopenharmony_ci if (strcmp(tlv->tlvName, MSG_EXT_NAME_APP_FD) != 0) { 5969570cc8Sopenharmony_ci continue; 6069570cc8Sopenharmony_ci } 6169570cc8Sopenharmony_ci std::string key((char *)data + sizeof(AppSpawnTlvExt)); 6269570cc8Sopenharmony_ci if (isColdRun) { 6369570cc8Sopenharmony_ci std::string envKey = std::string(APP_FDENV_PREFIX) + key; 6469570cc8Sopenharmony_ci char *fdChar = getenv(envKey.c_str()); 6569570cc8Sopenharmony_ci APPSPAWN_CHECK(fdChar != NULL, continue, "getfd from env failed %{public}s", envKey.c_str()); 6669570cc8Sopenharmony_ci int fd = atoi(fdChar); 6769570cc8Sopenharmony_ci APPSPAWN_CHECK(fd > 0, continue, "getfd from env atoi errno %{public}s,%{public}d", envKey.c_str(), fd); 6869570cc8Sopenharmony_ci fdMap[key] = fd; 6969570cc8Sopenharmony_ci } else { 7069570cc8Sopenharmony_ci APPSPAWN_CHECK(findFdIndex < recvCtx.fdCount && recvCtx.fds[findFdIndex] > 0, 7169570cc8Sopenharmony_ci return -1, "invalid fd info %{public}d %{public}d", findFdIndex, recvCtx.fds[findFdIndex]); 7269570cc8Sopenharmony_ci fdMap[key] = recvCtx.fds[findFdIndex++]; 7369570cc8Sopenharmony_ci if (findFdIndex >= recvCtx.fdCount) { 7469570cc8Sopenharmony_ci break; 7569570cc8Sopenharmony_ci } 7669570cc8Sopenharmony_ci } 7769570cc8Sopenharmony_ci } 7869570cc8Sopenharmony_ci return 0; 7969570cc8Sopenharmony_ci} 8069570cc8Sopenharmony_ci 8169570cc8Sopenharmony_cistatic int RunChildThread(const AppSpawnMgr *content, const AppSpawningCtx *property) 8269570cc8Sopenharmony_ci{ 8369570cc8Sopenharmony_ci std::string checkExit; 8469570cc8Sopenharmony_ci if (OHOS::system::GetBoolParameter("persist.init.debug.checkexit", true)) { 8569570cc8Sopenharmony_ci checkExit = std::to_string(getpid()); 8669570cc8Sopenharmony_ci } 8769570cc8Sopenharmony_ci setenv(APPSPAWN_CHECK_EXIT, checkExit.c_str(), true); 8869570cc8Sopenharmony_ci if (CheckAppMsgFlagsSet(property, APP_FLAGS_CHILDPROCESS)) { 8969570cc8Sopenharmony_ci std::map<std::string, int> fdMap; 9069570cc8Sopenharmony_ci BuildFdInfoMap(property->message, fdMap, IsColdRunMode(content)); 9169570cc8Sopenharmony_ci AppSpawnEnvClear((AppSpawnContent *)&content->content, (AppSpawnClient *)&property->client); 9269570cc8Sopenharmony_ci OHOS::AppExecFwk::MainThread::StartChild(fdMap); 9369570cc8Sopenharmony_ci } else { 9469570cc8Sopenharmony_ci AppSpawnEnvClear((AppSpawnContent *)&content->content, (AppSpawnClient *)&property->client); 9569570cc8Sopenharmony_ci OHOS::AppExecFwk::MainThread::Start(); 9669570cc8Sopenharmony_ci } 9769570cc8Sopenharmony_ci unsetenv(APPSPAWN_CHECK_EXIT); 9869570cc8Sopenharmony_ci return 0; 9969570cc8Sopenharmony_ci} 10069570cc8Sopenharmony_ci 10169570cc8Sopenharmony_cistatic int RunChildProcessor(AppSpawnContent *content, AppSpawnClient *client) 10269570cc8Sopenharmony_ci{ 10369570cc8Sopenharmony_ci APPSPAWN_CHECK(client != NULL && content != NULL, return -1, "Invalid client"); 10469570cc8Sopenharmony_ci AppSpawningCtx *property = reinterpret_cast<AppSpawningCtx *>(client); 10569570cc8Sopenharmony_ci 10669570cc8Sopenharmony_ci return RunChildThread(reinterpret_cast<AppSpawnMgr *>(content), property); 10769570cc8Sopenharmony_ci} 10869570cc8Sopenharmony_ci 10969570cc8Sopenharmony_ciAPPSPAWN_STATIC int PreLoadNativeSpawn(AppSpawnMgr *content) 11069570cc8Sopenharmony_ci{ 11169570cc8Sopenharmony_ci content->content.mode = MODE_FOR_NATIVE_SPAWN; 11269570cc8Sopenharmony_ci RegChildLooper(&content->content, RunChildProcessor); 11369570cc8Sopenharmony_ci return 0; 11469570cc8Sopenharmony_ci} 11569570cc8Sopenharmony_ci 11669570cc8Sopenharmony_ciMODULE_CONSTRUCTOR(void) 11769570cc8Sopenharmony_ci{ 11869570cc8Sopenharmony_ci APPSPAWN_LOGV("Load native module ..."); 11969570cc8Sopenharmony_ci AddPreloadHook(HOOK_PRIO_HIGHEST, PreLoadNativeSpawn); 12069570cc8Sopenharmony_ci}