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_test_cmder.h" 1769570cc8Sopenharmony_ci 1869570cc8Sopenharmony_ci#include <cerrno> 1969570cc8Sopenharmony_ci#include <cstdint> 2069570cc8Sopenharmony_ci#include <cstdio> 2169570cc8Sopenharmony_ci#include <cstdlib> 2269570cc8Sopenharmony_ci#include <fcntl.h> 2369570cc8Sopenharmony_ci#include <string> 2469570cc8Sopenharmony_ci#include <termios.h> 2569570cc8Sopenharmony_ci#include <unistd.h> 2669570cc8Sopenharmony_ci 2769570cc8Sopenharmony_ci#include <sys/stat.h> 2869570cc8Sopenharmony_ci 2969570cc8Sopenharmony_ci#include "appspawn.h" 3069570cc8Sopenharmony_ci#include "appspawn_msg.h" 3169570cc8Sopenharmony_ci#include "appspawn_utils.h" 3269570cc8Sopenharmony_ci#include "cJSON.h" 3369570cc8Sopenharmony_ci#include "command_lexer.h" 3469570cc8Sopenharmony_ci#include "json_utils.h" 3569570cc8Sopenharmony_ci#include "securec.h" 3669570cc8Sopenharmony_ci#include "thread_manager.h" 3769570cc8Sopenharmony_ci 3869570cc8Sopenharmony_ci#define MAX_THREAD 10 3969570cc8Sopenharmony_ci#define MAX_SEND 200 4069570cc8Sopenharmony_ci#define PTY_PATH_SIZE 128 4169570cc8Sopenharmony_ci 4269570cc8Sopenharmony_cinamespace OHOS { 4369570cc8Sopenharmony_cinamespace AppSpawnModuleTest { 4469570cc8Sopenharmony_cistatic const std::string g_defaultAppInfo = "{ \ 4569570cc8Sopenharmony_ci \"msg-type\": \"MSG_APP_SPAWN\", \ 4669570cc8Sopenharmony_ci \"msg-flags\": [1, 2 ], \ 4769570cc8Sopenharmony_ci \"process-name\" : \"com.example.myapplication\", \ 4869570cc8Sopenharmony_ci \"dac-info\" : { \ 4969570cc8Sopenharmony_ci \"uid\" : 20010043, \ 5069570cc8Sopenharmony_ci \"gid\" : 20010043,\ 5169570cc8Sopenharmony_ci \"gid-table\" : [],\ 5269570cc8Sopenharmony_ci \"user-name\" : \"\" \ 5369570cc8Sopenharmony_ci },\ 5469570cc8Sopenharmony_ci \"access-token\" : {\ 5569570cc8Sopenharmony_ci \"accessTokenIdEx\" : 537854093\ 5669570cc8Sopenharmony_ci },\ 5769570cc8Sopenharmony_ci \"permission\" : [\ 5869570cc8Sopenharmony_ci \"ohos.permission.READ_IMAGEVIDEO\",\ 5969570cc8Sopenharmony_ci \"ohos.permission.FILE_CROSS_APP\",\ 6069570cc8Sopenharmony_ci \"ohos.permission.ACTIVATE_THEME_PACKAGE\"\ 6169570cc8Sopenharmony_ci ],\ 6269570cc8Sopenharmony_ci \"internet-permission\" : {\ 6369570cc8Sopenharmony_ci \"set-allow-internet\" : 0,\ 6469570cc8Sopenharmony_ci \"allow-internet\" : 0\ 6569570cc8Sopenharmony_ci },\ 6669570cc8Sopenharmony_ci \"bundle-info\" : {\ 6769570cc8Sopenharmony_ci \"bundle-index\" : 0,\ 6869570cc8Sopenharmony_ci \"bundle-name\" : \"com.example.myapplication\" \ 6969570cc8Sopenharmony_ci },\ 7069570cc8Sopenharmony_ci \"owner-id\" : \"\",\ 7169570cc8Sopenharmony_ci \"render-cmd\" : \"1234567890\",\ 7269570cc8Sopenharmony_ci \"domain-info\" : {\ 7369570cc8Sopenharmony_ci \"hap-flags\" : 0,\ 7469570cc8Sopenharmony_ci \"apl\" : \"system_core\"\ 7569570cc8Sopenharmony_ci },\ 7669570cc8Sopenharmony_ci \"ext-info\" : [\ 7769570cc8Sopenharmony_ci {\ 7869570cc8Sopenharmony_ci \"name\" : \"test\",\ 7969570cc8Sopenharmony_ci \"value\" : \"4444444444444444444\" \ 8069570cc8Sopenharmony_ci } \ 8169570cc8Sopenharmony_ci ]\ 8269570cc8Sopenharmony_ci}"; 8369570cc8Sopenharmony_ci 8469570cc8Sopenharmony_cistatic const char *APPSPAWN_TEST_USAGE = "usage: AppSpawnTest <options> \n" 8569570cc8Sopenharmony_ci "options list:\n" 8669570cc8Sopenharmony_ci " --help list available commands\n" 8769570cc8Sopenharmony_ci " --file xx file path with app info\n" 8869570cc8Sopenharmony_ci " --thread xx use multi-thread to send message\n" 8969570cc8Sopenharmony_ci " --type xx send msg type \n" 9069570cc8Sopenharmony_ci " --pid xx render terminate pid\n" 9169570cc8Sopenharmony_ci " --mode nwebspawn send message to nwebspawn service\n" 9269570cc8Sopenharmony_ci " --mode nativespawn send message to nativespawn service\n"; 9369570cc8Sopenharmony_ci 9469570cc8Sopenharmony_ciint AppSpawnTestCommander::ProcessArgs(int argc, char *const argv[]) 9569570cc8Sopenharmony_ci{ 9669570cc8Sopenharmony_ci int sendMsg = 0; 9769570cc8Sopenharmony_ci msgType_ = MAX_TYPE_INVALID; 9869570cc8Sopenharmony_ci for (int32_t i = 0; i < argc; i++) { 9969570cc8Sopenharmony_ci if (argv[i] == nullptr) { 10069570cc8Sopenharmony_ci continue; 10169570cc8Sopenharmony_ci } 10269570cc8Sopenharmony_ci if (strcmp(argv[i], "--file") == 0 && ((i + 1) < argc)) { // test file 10369570cc8Sopenharmony_ci i++; 10469570cc8Sopenharmony_ci testFileName_ = argv[i]; 10569570cc8Sopenharmony_ci sendMsg = 1; 10669570cc8Sopenharmony_ci } else if (strcmp(argv[i], "--thread") == 0 && ((i + 1) < argc)) { // use thread 10769570cc8Sopenharmony_ci i++; 10869570cc8Sopenharmony_ci threadCount_ = atoi(argv[i]); 10969570cc8Sopenharmony_ci if (threadCount_ > MAX_THREAD) { 11069570cc8Sopenharmony_ci threadCount_ = MAX_THREAD; 11169570cc8Sopenharmony_ci } 11269570cc8Sopenharmony_ci sendMsg = 1; 11369570cc8Sopenharmony_ci } else if (strcmp(argv[i], "--mode") == 0 && ((i + 1) < argc)) { 11469570cc8Sopenharmony_ci i++; 11569570cc8Sopenharmony_ci if (strcmp(argv[i], "nwebspawn") == 0) { 11669570cc8Sopenharmony_ci appSpawn_ = 0; 11769570cc8Sopenharmony_ci } else if (strcmp(argv[i], "nativespawn") == 0) { 11869570cc8Sopenharmony_ci appSpawn_ = 2; // 2 is nwebspawn 11969570cc8Sopenharmony_ci } else { 12069570cc8Sopenharmony_ci appSpawn_ = 1; 12169570cc8Sopenharmony_ci } 12269570cc8Sopenharmony_ci sendMsg = 1; 12369570cc8Sopenharmony_ci } else if (strcmp(argv[i], "--type") == 0 && ((i + 1) < argc)) { 12469570cc8Sopenharmony_ci i++; 12569570cc8Sopenharmony_ci msgType_ = atoi(argv[i]); 12669570cc8Sopenharmony_ci sendMsg = 1; 12769570cc8Sopenharmony_ci } else if (strcmp(argv[i], "--pid") == 0 && ((i + 1) < argc)) { 12869570cc8Sopenharmony_ci i++; 12969570cc8Sopenharmony_ci msgType_ = MSG_GET_RENDER_TERMINATION_STATUS; 13069570cc8Sopenharmony_ci terminatePid_ = atoi(argv[i]); 13169570cc8Sopenharmony_ci sendMsg = 1; 13269570cc8Sopenharmony_ci } else if (strcmp(argv[i], "--help") == 0) { 13369570cc8Sopenharmony_ci printf("%s\n", APPSPAWN_TEST_USAGE); 13469570cc8Sopenharmony_ci return 1; 13569570cc8Sopenharmony_ci } else if (strcmp(argv[i], "--send") == 0 || strcmp(argv[i], "send") == 0) { 13669570cc8Sopenharmony_ci sendMsg = 1; 13769570cc8Sopenharmony_ci } 13869570cc8Sopenharmony_ci } 13969570cc8Sopenharmony_ci if (sendMsg == 0) { 14069570cc8Sopenharmony_ci printf("%s\n", APPSPAWN_TEST_USAGE); 14169570cc8Sopenharmony_ci return 1; 14269570cc8Sopenharmony_ci } 14369570cc8Sopenharmony_ci return 0; 14469570cc8Sopenharmony_ci} 14569570cc8Sopenharmony_ci 14669570cc8Sopenharmony_ciuint32_t AppSpawnTestCommander::GetUint32ArrayFromJson(const cJSON *json, 14769570cc8Sopenharmony_ci const char *name, uint32_t dataArray[], uint32_t maxCount) 14869570cc8Sopenharmony_ci{ 14969570cc8Sopenharmony_ci APPSPAWN_CHECK(json != NULL, return 0, "Invalid json"); 15069570cc8Sopenharmony_ci APPSPAWN_CHECK(name != NULL, return 0, "Invalid name"); 15169570cc8Sopenharmony_ci APPSPAWN_CHECK(dataArray != NULL, return 0, "Invalid dataArray"); 15269570cc8Sopenharmony_ci APPSPAWN_CHECK(cJSON_IsObject(json), return 0, "json is not object."); 15369570cc8Sopenharmony_ci cJSON *array = cJSON_GetObjectItemCaseSensitive(json, name); 15469570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(array != NULL, return 0); 15569570cc8Sopenharmony_ci APPSPAWN_CHECK(cJSON_IsArray(array), return 0, "json is not object."); 15669570cc8Sopenharmony_ci 15769570cc8Sopenharmony_ci uint32_t count = 0; 15869570cc8Sopenharmony_ci uint32_t arrayLen = cJSON_GetArraySize(array); 15969570cc8Sopenharmony_ci for (int i = 0; i < arrayLen; i++) { 16069570cc8Sopenharmony_ci cJSON *item = cJSON_GetArrayItem(array, i); 16169570cc8Sopenharmony_ci uint32_t value = (uint32_t)cJSON_GetNumberValue(item); 16269570cc8Sopenharmony_ci if (count < maxCount) { 16369570cc8Sopenharmony_ci dataArray[count++] = value; 16469570cc8Sopenharmony_ci } 16569570cc8Sopenharmony_ci } 16669570cc8Sopenharmony_ci return count; 16769570cc8Sopenharmony_ci} 16869570cc8Sopenharmony_ci 16969570cc8Sopenharmony_ciint AppSpawnTestCommander::AddBundleInfoFromJson(const cJSON *appInfoConfig, AppSpawnReqMsgHandle reqHandle) 17069570cc8Sopenharmony_ci{ 17169570cc8Sopenharmony_ci cJSON *config = cJSON_GetObjectItemCaseSensitive(appInfoConfig, "bundle-info"); 17269570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(config, return 0); 17369570cc8Sopenharmony_ci 17469570cc8Sopenharmony_ci uint32_t bundleIndex = GetIntValueFromJsonObj(config, "bundle-index", 0); 17569570cc8Sopenharmony_ci char *bundleName = GetStringFromJsonObj(config, "bundle-name"); 17669570cc8Sopenharmony_ci int ret = AppSpawnReqMsgSetBundleInfo(reqHandle, bundleIndex, bundleName); 17769570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "Failed to add bundle info req %{public}s", bundleName); 17869570cc8Sopenharmony_ci return 0; 17969570cc8Sopenharmony_ci} 18069570cc8Sopenharmony_ci 18169570cc8Sopenharmony_ciint AppSpawnTestCommander::AddDacInfoFromJson(const cJSON *appInfoConfig, AppSpawnReqMsgHandle reqHandle) 18269570cc8Sopenharmony_ci{ 18369570cc8Sopenharmony_ci cJSON *config = cJSON_GetObjectItemCaseSensitive(appInfoConfig, "dac-info"); 18469570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(config, return 0); 18569570cc8Sopenharmony_ci 18669570cc8Sopenharmony_ci AppDacInfo info = {}; 18769570cc8Sopenharmony_ci info.uid = GetIntValueFromJsonObj(config, "uid", 0); 18869570cc8Sopenharmony_ci info.gid = GetIntValueFromJsonObj(config, "gid", 0); 18969570cc8Sopenharmony_ci info.gidCount = GetUint32ArrayFromJson(config, "gid-table", info.gidTable, APP_MAX_GIDS); 19069570cc8Sopenharmony_ci char *userName = GetStringFromJsonObj(config, "user-name"); 19169570cc8Sopenharmony_ci if (userName != nullptr) { 19269570cc8Sopenharmony_ci int ret = strcpy_s(info.userName, sizeof(info.userName), userName); 19369570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "Failed to add userName info req %{public}s", userName); 19469570cc8Sopenharmony_ci } 19569570cc8Sopenharmony_ci return AppSpawnReqMsgSetAppDacInfo(reqHandle, &info); 19669570cc8Sopenharmony_ci} 19769570cc8Sopenharmony_ci 19869570cc8Sopenharmony_ciint AppSpawnTestCommander::AddInternetPermissionInfoFromJson( 19969570cc8Sopenharmony_ci const cJSON *appInfoConfig, AppSpawnReqMsgHandle reqHandle) 20069570cc8Sopenharmony_ci{ 20169570cc8Sopenharmony_ci cJSON *config = cJSON_GetObjectItemCaseSensitive(appInfoConfig, "internet-permission"); 20269570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(config, return 0); 20369570cc8Sopenharmony_ci 20469570cc8Sopenharmony_ci uint8_t setAllowInternet = GetIntValueFromJsonObj(config, "set-allow-internet", 0); 20569570cc8Sopenharmony_ci uint8_t allowInternet = GetIntValueFromJsonObj(config, "allow-internet", 0); 20669570cc8Sopenharmony_ci return AppSpawnReqMsgSetAppInternetPermissionInfo(reqHandle, allowInternet, setAllowInternet); 20769570cc8Sopenharmony_ci} 20869570cc8Sopenharmony_ci 20969570cc8Sopenharmony_ciint AppSpawnTestCommander::AddAccessTokenFromJson(const cJSON *appInfoConfig, AppSpawnReqMsgHandle reqHandle) 21069570cc8Sopenharmony_ci{ 21169570cc8Sopenharmony_ci cJSON *config = cJSON_GetObjectItemCaseSensitive(appInfoConfig, "access-token"); 21269570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(config, return 0); 21369570cc8Sopenharmony_ci 21469570cc8Sopenharmony_ci uint64_t accessTokenIdEx = GetIntValueFromJsonObj(config, "accessTokenIdEx", 0); 21569570cc8Sopenharmony_ci return AppSpawnReqMsgSetAppAccessToken(reqHandle, accessTokenIdEx); 21669570cc8Sopenharmony_ci} 21769570cc8Sopenharmony_ci 21869570cc8Sopenharmony_ciint AppSpawnTestCommander::AddDomainInfoFromJson(const cJSON *appInfoConfig, AppSpawnReqMsgHandle reqHandle) 21969570cc8Sopenharmony_ci{ 22069570cc8Sopenharmony_ci cJSON *config = cJSON_GetObjectItemCaseSensitive(appInfoConfig, "domain-info"); 22169570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(config, return 0); 22269570cc8Sopenharmony_ci 22369570cc8Sopenharmony_ci uint32_t hapFlags = GetIntValueFromJsonObj(config, "hap-flags", 0); 22469570cc8Sopenharmony_ci char *apl = GetStringFromJsonObj(config, "apl"); 22569570cc8Sopenharmony_ci int ret = AppSpawnReqMsgSetAppDomainInfo(reqHandle, hapFlags, apl); 22669570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "Failed to domain info"); 22769570cc8Sopenharmony_ci return 0; 22869570cc8Sopenharmony_ci} 22969570cc8Sopenharmony_ci 23069570cc8Sopenharmony_ciint AppSpawnTestCommander::AddExtTlv(const cJSON *appInfoConfig, AppSpawnReqMsgHandle reqHandle) 23169570cc8Sopenharmony_ci{ 23269570cc8Sopenharmony_ci cJSON *configs = cJSON_GetObjectItemCaseSensitive(appInfoConfig, "ext-info"); 23369570cc8Sopenharmony_ci APPSPAWN_CHECK_ONLY_EXPER(configs != nullptr, return 0); 23469570cc8Sopenharmony_ci 23569570cc8Sopenharmony_ci int ret = 0; 23669570cc8Sopenharmony_ci uint32_t count = cJSON_GetArraySize(configs); 23769570cc8Sopenharmony_ci for (unsigned int j = 0; j < count; j++) { 23869570cc8Sopenharmony_ci cJSON *config = cJSON_GetArrayItem(configs, j); 23969570cc8Sopenharmony_ci 24069570cc8Sopenharmony_ci char *name = GetStringFromJsonObj(config, "name"); 24169570cc8Sopenharmony_ci char *value = GetStringFromJsonObj(config, "value"); 24269570cc8Sopenharmony_ci APPSPAWN_LOGV("ext-info %{public}s %{public}s", name, value); 24369570cc8Sopenharmony_ci ret = AppSpawnReqMsgAddStringInfo(reqHandle, name, value); 24469570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "Failed to add ext name %{public}s", name); 24569570cc8Sopenharmony_ci } 24669570cc8Sopenharmony_ci 24769570cc8Sopenharmony_ci // 添加一个二进制的扩展元素 24869570cc8Sopenharmony_ci AppDacInfo dacInfo{}; 24969570cc8Sopenharmony_ci dacInfo.uid = 101; // 101 test data 25069570cc8Sopenharmony_ci dacInfo.gid = 101; // 101 test data 25169570cc8Sopenharmony_ci dacInfo.gidTable[0] = 101; // 101 test data 25269570cc8Sopenharmony_ci dacInfo.gidCount = 1; 25369570cc8Sopenharmony_ci (void)strcpy_s(dacInfo.userName, sizeof(dacInfo.userName), processName_.c_str()); 25469570cc8Sopenharmony_ci ret = AppSpawnReqMsgAddExtInfo(reqHandle, 25569570cc8Sopenharmony_ci "app-dac-info", reinterpret_cast<uint8_t *>(&dacInfo), sizeof(dacInfo)); 25669570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "Failed to add ext name app-info"); 25769570cc8Sopenharmony_ci return ret; 25869570cc8Sopenharmony_ci} 25969570cc8Sopenharmony_ci 26069570cc8Sopenharmony_ciint AppSpawnTestCommander::BuildMsgFromJson(const cJSON *appInfoConfig, AppSpawnReqMsgHandle reqHandle) 26169570cc8Sopenharmony_ci{ 26269570cc8Sopenharmony_ci int ret = AddBundleInfoFromJson(appInfoConfig, reqHandle); 26369570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "Failed to add dac %{public}s", processName_.c_str()); 26469570cc8Sopenharmony_ci 26569570cc8Sopenharmony_ci ret = AddDomainInfoFromJson(appInfoConfig, reqHandle); 26669570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "Failed to add dac %{public}s", processName_.c_str()); 26769570cc8Sopenharmony_ci 26869570cc8Sopenharmony_ci ret = AddDacInfoFromJson(appInfoConfig, reqHandle); 26969570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "Failed to add dac %{public}s", processName_.c_str()); 27069570cc8Sopenharmony_ci 27169570cc8Sopenharmony_ci ret = AddAccessTokenFromJson(appInfoConfig, reqHandle); 27269570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "Failed to add access token %{public}s", processName_.c_str()); 27369570cc8Sopenharmony_ci 27469570cc8Sopenharmony_ci cJSON *obj = cJSON_GetObjectItemCaseSensitive(appInfoConfig, "permission"); 27569570cc8Sopenharmony_ci if (obj != nullptr && cJSON_IsArray(obj)) { 27669570cc8Sopenharmony_ci int count = cJSON_GetArraySize(obj); 27769570cc8Sopenharmony_ci for (int i = 0; i < count; i++) { 27869570cc8Sopenharmony_ci char *value = cJSON_GetStringValue(cJSON_GetArrayItem(obj, i)); 27969570cc8Sopenharmony_ci APPSPAWN_LOGV("permission %{public}s ", value); 28069570cc8Sopenharmony_ci ret = AppSpawnReqMsgAddPermission(reqHandle, value); 28169570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "Failed to permission %{public}s", value); 28269570cc8Sopenharmony_ci } 28369570cc8Sopenharmony_ci } 28469570cc8Sopenharmony_ci 28569570cc8Sopenharmony_ci ret = AddInternetPermissionInfoFromJson(appInfoConfig, reqHandle); 28669570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "Failed to internet info %{public}s", processName_.c_str()); 28769570cc8Sopenharmony_ci 28869570cc8Sopenharmony_ci std::string ownerId = GetStringFromJsonObj(appInfoConfig, "owner-id"); 28969570cc8Sopenharmony_ci if (!ownerId.empty()) { 29069570cc8Sopenharmony_ci ret = AppSpawnReqMsgSetAppOwnerId(reqHandle, ownerId.c_str()); 29169570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "Failed to ownerid %{public}s", processName_.c_str()); 29269570cc8Sopenharmony_ci } 29369570cc8Sopenharmony_ci 29469570cc8Sopenharmony_ci std::string renderCmd = GetStringFromJsonObj(appInfoConfig, "render-cmd"); 29569570cc8Sopenharmony_ci if (!renderCmd.empty()) { 29669570cc8Sopenharmony_ci ret = AppSpawnReqMsgAddStringInfo(reqHandle, MSG_EXT_NAME_RENDER_CMD, renderCmd.c_str()); 29769570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return -1, "Failed to add renderCmd %{public}s", renderCmd.c_str()); 29869570cc8Sopenharmony_ci } 29969570cc8Sopenharmony_ci return AddExtTlv(appInfoConfig, reqHandle); 30069570cc8Sopenharmony_ci} 30169570cc8Sopenharmony_ci 30269570cc8Sopenharmony_ciint AppSpawnTestCommander::CreateOtherMsg(AppSpawnReqMsgHandle &reqHandle, pid_t pid) 30369570cc8Sopenharmony_ci{ 30469570cc8Sopenharmony_ci if (msgType_ == MSG_GET_RENDER_TERMINATION_STATUS) { 30569570cc8Sopenharmony_ci int ret = AppSpawnTerminateMsgCreate(pid, &reqHandle); 30669570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "Failed to termination message req %{public}s", processName_.c_str()); 30769570cc8Sopenharmony_ci } 30869570cc8Sopenharmony_ci if (msgType_ == MSG_DUMP) { 30969570cc8Sopenharmony_ci int ret = AppSpawnReqMsgCreate(static_cast<AppSpawnMsgType>(msgType_), processName_.c_str(), &reqHandle); 31069570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "Failed to dump req %{public}s", processName_.c_str()); 31169570cc8Sopenharmony_ci ret = AppSpawnReqMsgAddStringInfo(reqHandle, "pty-name", ptyName_.c_str()); 31269570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return -1, "Failed to add ptyName_ %{public}s", ptyName_.c_str()); 31369570cc8Sopenharmony_ci } 31469570cc8Sopenharmony_ci return 0; 31569570cc8Sopenharmony_ci} 31669570cc8Sopenharmony_ci 31769570cc8Sopenharmony_cistatic uint32_t GetMsgTypeFromJson(const cJSON *json) 31869570cc8Sopenharmony_ci{ 31969570cc8Sopenharmony_ci const char *msgType = GetStringFromJsonObj(json, "msg-type"); 32069570cc8Sopenharmony_ci if (msgType == nullptr) { 32169570cc8Sopenharmony_ci return MSG_APP_SPAWN; 32269570cc8Sopenharmony_ci } 32369570cc8Sopenharmony_ci if (strcmp(msgType, "MSG_SPAWN_NATIVE_PROCESS") == 0) { 32469570cc8Sopenharmony_ci return MSG_SPAWN_NATIVE_PROCESS; 32569570cc8Sopenharmony_ci } 32669570cc8Sopenharmony_ci if (strcmp(msgType, "MSG_GET_RENDER_TERMINATION_STATUS") == 0) { 32769570cc8Sopenharmony_ci return MSG_GET_RENDER_TERMINATION_STATUS; 32869570cc8Sopenharmony_ci } 32969570cc8Sopenharmony_ci if (strcmp(msgType, "MSG_DUMP") == 0) { 33069570cc8Sopenharmony_ci return MSG_DUMP; 33169570cc8Sopenharmony_ci } 33269570cc8Sopenharmony_ci return MSG_APP_SPAWN; 33369570cc8Sopenharmony_ci} 33469570cc8Sopenharmony_ci 33569570cc8Sopenharmony_ciint AppSpawnTestCommander::CreateMsg(AppSpawnReqMsgHandle &reqHandle, 33669570cc8Sopenharmony_ci const char *defaultConfig, uint32_t defMsgType) 33769570cc8Sopenharmony_ci{ 33869570cc8Sopenharmony_ci int ret = APPSPAWN_SYSTEM_ERROR; 33969570cc8Sopenharmony_ci if (clientHandle_ == NULL) { 34069570cc8Sopenharmony_ci ret = AppSpawnClientInit(appSpawn_ ? APPSPAWN_SERVER_NAME : NWEBSPAWN_SERVER_NAME, &clientHandle_); 34169570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return -1, "Failed to create client %{public}d", appSpawn_); 34269570cc8Sopenharmony_ci } 34369570cc8Sopenharmony_ci reqHandle = INVALID_REQ_HANDLE; 34469570cc8Sopenharmony_ci if (appInfoConfig_) { 34569570cc8Sopenharmony_ci cJSON_Delete(appInfoConfig_); 34669570cc8Sopenharmony_ci appInfoConfig_ = nullptr; 34769570cc8Sopenharmony_ci } 34869570cc8Sopenharmony_ci if (!testFileName_.empty()) { 34969570cc8Sopenharmony_ci appInfoConfig_ = GetJsonObjFromFile(testFileName_.c_str()); 35069570cc8Sopenharmony_ci if (appInfoConfig_ == nullptr) { 35169570cc8Sopenharmony_ci printf("Failed to load file %s, so use default info \n", testFileName_.c_str()); 35269570cc8Sopenharmony_ci } 35369570cc8Sopenharmony_ci } 35469570cc8Sopenharmony_ci if (appInfoConfig_ == nullptr) { 35569570cc8Sopenharmony_ci appInfoConfig_ = cJSON_Parse(defaultConfig); 35669570cc8Sopenharmony_ci } 35769570cc8Sopenharmony_ci if (appInfoConfig_ == nullptr) { 35869570cc8Sopenharmony_ci printf("Invalid app info \n"); 35969570cc8Sopenharmony_ci return APPSPAWN_SYSTEM_ERROR; 36069570cc8Sopenharmony_ci } 36169570cc8Sopenharmony_ci processName_ = GetStringFromJsonObj(appInfoConfig_, "process-name"); 36269570cc8Sopenharmony_ci if (processName_.empty()) { 36369570cc8Sopenharmony_ci processName_ = "com.example.myapplication"; 36469570cc8Sopenharmony_ci } 36569570cc8Sopenharmony_ci msgType_ = (msgType_ == MAX_TYPE_INVALID) ? GetMsgTypeFromJson(appInfoConfig_) : msgType_; 36669570cc8Sopenharmony_ci msgType_ = (defMsgType != MAX_TYPE_INVALID) ? defMsgType : msgType_; 36769570cc8Sopenharmony_ci if (msgType_ == MSG_DUMP) { 36869570cc8Sopenharmony_ci return CreateOtherMsg(reqHandle, 0); 36969570cc8Sopenharmony_ci } else if (msgType_ == MSG_GET_RENDER_TERMINATION_STATUS) { 37069570cc8Sopenharmony_ci pid_t pid = GetIntValueFromJsonObj(appInfoConfig_, "pid", 0); 37169570cc8Sopenharmony_ci return CreateOtherMsg(reqHandle, pid); 37269570cc8Sopenharmony_ci } 37369570cc8Sopenharmony_ci ret = AppSpawnReqMsgCreate(static_cast<AppSpawnMsgType>(msgType_), processName_.c_str(), &reqHandle); 37469570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return ret, "Failed to create req %{public}s", processName_.c_str()); 37569570cc8Sopenharmony_ci 37669570cc8Sopenharmony_ci uint32_t msgFlags[64] = {}; // 64 37769570cc8Sopenharmony_ci uint32_t count = GetUint32ArrayFromJson(appInfoConfig_, "msg-flags", msgFlags, ARRAY_LENGTH(msgFlags)); 37869570cc8Sopenharmony_ci for (uint32_t j = 0; j < count; j++) { 37969570cc8Sopenharmony_ci (void)AppSpawnReqMsgSetAppFlag(reqHandle, static_cast<AppFlagsIndex>(msgFlags[j])); 38069570cc8Sopenharmony_ci } 38169570cc8Sopenharmony_ci (void)AppSpawnReqMsgSetAppFlag(reqHandle, APP_FLAGS_IGNORE_SANDBOX); 38269570cc8Sopenharmony_ci ret = BuildMsgFromJson(appInfoConfig_, reqHandle); 38369570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, AppSpawnReqMsgFree(reqHandle); 38469570cc8Sopenharmony_ci return ret, "Failed to build req %{public}s", processName_.c_str()); 38569570cc8Sopenharmony_ci return ret; 38669570cc8Sopenharmony_ci} 38769570cc8Sopenharmony_ci 38869570cc8Sopenharmony_ciint AppSpawnTestCommander::SendMsg() 38969570cc8Sopenharmony_ci{ 39069570cc8Sopenharmony_ci const char *server = appSpawn_ == 1 ? APPSPAWN_SERVER_NAME : (appSpawn_ == 2 ? NATIVESPAWN_SERVER_NAME : 39169570cc8Sopenharmony_ci NWEBSPAWN_SERVER_NAME); 39269570cc8Sopenharmony_ci printf("Send msg to server '%s' \n", server); 39369570cc8Sopenharmony_ci AppSpawnReqMsgHandle reqHandle = INVALID_REQ_HANDLE; 39469570cc8Sopenharmony_ci int ret = 0; 39569570cc8Sopenharmony_ci if (msgType_ == MSG_DUMP) { 39669570cc8Sopenharmony_ci while (!dumpFlags) { 39769570cc8Sopenharmony_ci usleep(20000); // 20000 39869570cc8Sopenharmony_ci } 39969570cc8Sopenharmony_ci ret = CreateOtherMsg(reqHandle, 0); 40069570cc8Sopenharmony_ci } else if (msgType_ == MSG_GET_RENDER_TERMINATION_STATUS) { 40169570cc8Sopenharmony_ci ret = CreateOtherMsg(reqHandle, terminatePid_); 40269570cc8Sopenharmony_ci } else { 40369570cc8Sopenharmony_ci ret = CreateMsg(reqHandle, g_defaultAppInfo.c_str()); 40469570cc8Sopenharmony_ci } 40569570cc8Sopenharmony_ci AppSpawnResult result = {ret, 0}; 40669570cc8Sopenharmony_ci if (ret == 0) { 40769570cc8Sopenharmony_ci ret = AppSpawnClientSendMsg(clientHandle_, reqHandle, &result); 40869570cc8Sopenharmony_ci } 40969570cc8Sopenharmony_ci switch (msgType_) { 41069570cc8Sopenharmony_ci case MSG_APP_SPAWN: 41169570cc8Sopenharmony_ci if (result.result == 0) { 41269570cc8Sopenharmony_ci printf("Spawn app %s success, pid %d \n", processName_.c_str(), result.pid); 41369570cc8Sopenharmony_ci } else { 41469570cc8Sopenharmony_ci printf("Spawn app %s fail, result 0x%x \n", processName_.c_str(), result.result); 41569570cc8Sopenharmony_ci } 41669570cc8Sopenharmony_ci break; 41769570cc8Sopenharmony_ci case MSG_SPAWN_NATIVE_PROCESS: 41869570cc8Sopenharmony_ci if (result.result == 0) { 41969570cc8Sopenharmony_ci printf("Spawn native app %s success, pid %d \n", processName_.c_str(), result.pid); 42069570cc8Sopenharmony_ci } else { 42169570cc8Sopenharmony_ci printf("Spawn native app %s fail, result 0x%x \n", processName_.c_str(), result.result); 42269570cc8Sopenharmony_ci } 42369570cc8Sopenharmony_ci break; 42469570cc8Sopenharmony_ci case MSG_GET_RENDER_TERMINATION_STATUS: 42569570cc8Sopenharmony_ci printf("Terminate app %s success, pid %d status 0x%x \n", 42669570cc8Sopenharmony_ci processName_.c_str(), result.pid, result.result); 42769570cc8Sopenharmony_ci break; 42869570cc8Sopenharmony_ci default: 42969570cc8Sopenharmony_ci printf("Dump server %s result %d \n", server, ret); 43069570cc8Sopenharmony_ci break; 43169570cc8Sopenharmony_ci } 43269570cc8Sopenharmony_ci msgType_ = MAX_TYPE_INVALID; 43369570cc8Sopenharmony_ci terminatePid_ = 0; 43469570cc8Sopenharmony_ci printf("Please input cmd: \n"); 43569570cc8Sopenharmony_ci return 0; 43669570cc8Sopenharmony_ci} 43769570cc8Sopenharmony_ci 43869570cc8Sopenharmony_ciint AppSpawnTestCommander::StartSendMsg() 43969570cc8Sopenharmony_ci{ 44069570cc8Sopenharmony_ci int ret = 0; 44169570cc8Sopenharmony_ci printf("Start send msg thread count %d file name %s \n", threadCount_, testFileName_.c_str()); 44269570cc8Sopenharmony_ci if (threadCount_ == 1) { 44369570cc8Sopenharmony_ci SendMsg(); 44469570cc8Sopenharmony_ci } else { 44569570cc8Sopenharmony_ci ThreadTaskHandle taskHandle = 0; 44669570cc8Sopenharmony_ci ret = ThreadMgrAddTask(threadMgr_, &taskHandle); 44769570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return 0, "Failed to add task "); 44869570cc8Sopenharmony_ci for (uint32_t index = 0; index < threadCount_; index++) { 44969570cc8Sopenharmony_ci ThreadMgrAddExecutor(threadMgr_, taskHandle, TaskExecutorProc, reinterpret_cast<ThreadContext *>(this)); 45069570cc8Sopenharmony_ci } 45169570cc8Sopenharmony_ci TaskSyncExecute(threadMgr_, taskHandle); 45269570cc8Sopenharmony_ci } 45369570cc8Sopenharmony_ci return 0; 45469570cc8Sopenharmony_ci} 45569570cc8Sopenharmony_ci 45669570cc8Sopenharmony_civoid AppSpawnTestCommander::TaskExecutorProc(ThreadTaskHandle handle, const ThreadContext *context) 45769570cc8Sopenharmony_ci{ 45869570cc8Sopenharmony_ci AppSpawnTestCommander *testCmder = AppSpawnTestCommander::ConvertTo(context); 45969570cc8Sopenharmony_ci testCmder->SendMsg(); 46069570cc8Sopenharmony_ci} 46169570cc8Sopenharmony_ci 46269570cc8Sopenharmony_civoid AppSpawnTestCommander::SendTaskFinish(ThreadTaskHandle handle, const ThreadContext *context) 46369570cc8Sopenharmony_ci{ 46469570cc8Sopenharmony_ci APPSPAWN_LOGV("SendTaskFinish %{public}u \n", handle); 46569570cc8Sopenharmony_ci} 46669570cc8Sopenharmony_ci 46769570cc8Sopenharmony_cistatic std::vector<std::string> g_args; 46869570cc8Sopenharmony_cistatic int HandleSplitString(const char *str, void *context) 46969570cc8Sopenharmony_ci{ 47069570cc8Sopenharmony_ci APPSPAWN_LOGV("HandleSplitString %{public}s ", str); 47169570cc8Sopenharmony_ci std::string value = str; 47269570cc8Sopenharmony_ci g_args.push_back(value); 47369570cc8Sopenharmony_ci return 0; 47469570cc8Sopenharmony_ci} 47569570cc8Sopenharmony_ci 47669570cc8Sopenharmony_ciint AppSpawnTestCommander::ProcessInputCmd(std::string &cmd) 47769570cc8Sopenharmony_ci{ 47869570cc8Sopenharmony_ci g_args.clear(); 47969570cc8Sopenharmony_ci int ret = StringSplit(cmd.c_str(), " ", nullptr, HandleSplitString); 48069570cc8Sopenharmony_ci std::vector<char *> options; 48169570cc8Sopenharmony_ci for (const auto &arg : g_args) { 48269570cc8Sopenharmony_ci if (!arg.empty()) { 48369570cc8Sopenharmony_ci options.push_back(const_cast<char *>(arg.c_str())); 48469570cc8Sopenharmony_ci } 48569570cc8Sopenharmony_ci } 48669570cc8Sopenharmony_ci (void)ProcessArgs(options.size(), options.data()); 48769570cc8Sopenharmony_ci StartSendMsg(); 48869570cc8Sopenharmony_ci return ret; 48969570cc8Sopenharmony_ci} 49069570cc8Sopenharmony_ci 49169570cc8Sopenharmony_civoid AppSpawnTestCommander::InputThread(ThreadTaskHandle handle, const ThreadContext *context) 49269570cc8Sopenharmony_ci{ 49369570cc8Sopenharmony_ci AppSpawnTestCommander *testCmder = AppSpawnTestCommander::ConvertTo(context); 49469570cc8Sopenharmony_ci char buffer[1024] = {0}; // 1024 test buffer max len 49569570cc8Sopenharmony_ci fd_set fds; 49669570cc8Sopenharmony_ci printf("Please input cmd: \n"); 49769570cc8Sopenharmony_ci while (1) { 49869570cc8Sopenharmony_ci FD_ZERO(&fds); 49969570cc8Sopenharmony_ci FD_SET(STDIN_FILENO, &fds); 50069570cc8Sopenharmony_ci int ret = select(STDIN_FILENO + 1, &fds, nullptr, nullptr, nullptr); 50169570cc8Sopenharmony_ci if (ret <= 0) { 50269570cc8Sopenharmony_ci if (testCmder->exit_) { 50369570cc8Sopenharmony_ci break; 50469570cc8Sopenharmony_ci } 50569570cc8Sopenharmony_ci continue; 50669570cc8Sopenharmony_ci } 50769570cc8Sopenharmony_ci ssize_t rlen = read(STDIN_FILENO, buffer, sizeof(buffer) - 1); 50869570cc8Sopenharmony_ci if (rlen <= 1) { 50969570cc8Sopenharmony_ci continue; 51069570cc8Sopenharmony_ci } 51169570cc8Sopenharmony_ci buffer[rlen - 1] = 0; 51269570cc8Sopenharmony_ci printf("Recv command: '%s' \n", buffer); 51369570cc8Sopenharmony_ci if (strncmp("quit", buffer, strlen("quit")) == 0) { 51469570cc8Sopenharmony_ci testCmder->exit_ = 1; 51569570cc8Sopenharmony_ci break; 51669570cc8Sopenharmony_ci } 51769570cc8Sopenharmony_ci if (strncmp("send", buffer, 4) == 0) { // 4 strlen("send") 51869570cc8Sopenharmony_ci std::string cmd(buffer); 51969570cc8Sopenharmony_ci testCmder->ProcessInputCmd(cmd); 52069570cc8Sopenharmony_ci printf("Please input cmd: \n"); 52169570cc8Sopenharmony_ci } 52269570cc8Sopenharmony_ci } 52369570cc8Sopenharmony_ci} 52469570cc8Sopenharmony_ci 52569570cc8Sopenharmony_civoid AppSpawnTestCommander::DumpThread(ThreadTaskHandle handle, const ThreadContext *context) 52669570cc8Sopenharmony_ci{ 52769570cc8Sopenharmony_ci AppSpawnTestCommander *testCmder = AppSpawnTestCommander::ConvertTo(context); 52869570cc8Sopenharmony_ci printf("Start dump thread \n"); 52969570cc8Sopenharmony_ci char buffer[10240] = {0}; // 1024 test buffer max len 53069570cc8Sopenharmony_ci fd_set fds; 53169570cc8Sopenharmony_ci while (1) { 53269570cc8Sopenharmony_ci testCmder->dumpFlags = 1; 53369570cc8Sopenharmony_ci FD_ZERO(&fds); 53469570cc8Sopenharmony_ci FD_SET(testCmder->ptyFd_, &fds); 53569570cc8Sopenharmony_ci int ret = select(testCmder->ptyFd_ + 1, &fds, nullptr, nullptr, nullptr); 53669570cc8Sopenharmony_ci if (ret <= 0) { 53769570cc8Sopenharmony_ci if (testCmder->exit_) { 53869570cc8Sopenharmony_ci break; 53969570cc8Sopenharmony_ci } 54069570cc8Sopenharmony_ci continue; 54169570cc8Sopenharmony_ci } 54269570cc8Sopenharmony_ci if (!FD_ISSET(testCmder->ptyFd_, &fds)) { 54369570cc8Sopenharmony_ci continue; 54469570cc8Sopenharmony_ci } 54569570cc8Sopenharmony_ci ssize_t rlen = read(testCmder->ptyFd_, buffer, sizeof(buffer) - 1); 54669570cc8Sopenharmony_ci while (rlen > 0) { 54769570cc8Sopenharmony_ci buffer[rlen] = '\0'; 54869570cc8Sopenharmony_ci printf("%s", buffer); 54969570cc8Sopenharmony_ci fflush(stdout); 55069570cc8Sopenharmony_ci rlen = read(testCmder->ptyFd_, buffer, sizeof(buffer) - 1); 55169570cc8Sopenharmony_ci } 55269570cc8Sopenharmony_ci } 55369570cc8Sopenharmony_ci} 55469570cc8Sopenharmony_ci 55569570cc8Sopenharmony_ciint AppSpawnTestCommander::Run() 55669570cc8Sopenharmony_ci{ 55769570cc8Sopenharmony_ci int ret = 0; 55869570cc8Sopenharmony_ci const char *name = appSpawn_ == 1 ? APPSPAWN_SERVER_NAME : (appSpawn_ == 2 ? NATIVESPAWN_SERVER_NAME : 55969570cc8Sopenharmony_ci NWEBSPAWN_SERVER_NAME); 56069570cc8Sopenharmony_ci if (clientHandle_ == NULL) { 56169570cc8Sopenharmony_ci ret = AppSpawnClientInit(name, &clientHandle_); 56269570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return -1, "Failed to create client %{public}s", name); 56369570cc8Sopenharmony_ci } 56469570cc8Sopenharmony_ci 56569570cc8Sopenharmony_ci InitPtyInterface(); 56669570cc8Sopenharmony_ci 56769570cc8Sopenharmony_ci ret = CreateThreadMgr(5, &threadMgr_); // 5 max thread 56869570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return -1, "Failed to create thread manager"); 56969570cc8Sopenharmony_ci 57069570cc8Sopenharmony_ci ret = ThreadMgrAddTask(threadMgr_, &inputHandle_); 57169570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return 0, "Failed to add task for thread "); 57269570cc8Sopenharmony_ci ThreadMgrAddExecutor(threadMgr_, inputHandle_, InputThread, this); 57369570cc8Sopenharmony_ci TaskExecute(threadMgr_, inputHandle_, SendTaskFinish, this); 57469570cc8Sopenharmony_ci 57569570cc8Sopenharmony_ci ret = ThreadMgrAddTask(threadMgr_, &dumpHandle_); 57669570cc8Sopenharmony_ci APPSPAWN_CHECK(ret == 0, return 0, "Failed to add task for thread "); 57769570cc8Sopenharmony_ci ThreadMgrAddExecutor(threadMgr_, dumpHandle_, DumpThread, this); 57869570cc8Sopenharmony_ci TaskExecute(threadMgr_, dumpHandle_, SendTaskFinish, this); 57969570cc8Sopenharmony_ci 58069570cc8Sopenharmony_ci StartSendMsg(); 58169570cc8Sopenharmony_ci 58269570cc8Sopenharmony_ci APPSPAWN_LOGV("Finish send msg \n"); 58369570cc8Sopenharmony_ci while (!exit_) { 58469570cc8Sopenharmony_ci usleep(200000); // 200000 200ms 58569570cc8Sopenharmony_ci } 58669570cc8Sopenharmony_ci ThreadMgrCancelTask(threadMgr_, inputHandle_); 58769570cc8Sopenharmony_ci ThreadMgrCancelTask(threadMgr_, dumpHandle_); 58869570cc8Sopenharmony_ci DestroyThreadMgr(threadMgr_); 58969570cc8Sopenharmony_ci threadMgr_ = nullptr; 59069570cc8Sopenharmony_ci inputHandle_ = 0; 59169570cc8Sopenharmony_ci dumpHandle_ = 0; 59269570cc8Sopenharmony_ci AppSpawnClientDestroy(clientHandle_); 59369570cc8Sopenharmony_ci clientHandle_ = nullptr; 59469570cc8Sopenharmony_ci return 0; 59569570cc8Sopenharmony_ci} 59669570cc8Sopenharmony_ci 59769570cc8Sopenharmony_ciint AppSpawnTestCommander::InitPtyInterface() 59869570cc8Sopenharmony_ci{ 59969570cc8Sopenharmony_ci // open master pty and get slave pty 60069570cc8Sopenharmony_ci int pfd = open("/dev/ptmx", O_RDWR | O_CLOEXEC | O_NOCTTY | O_NONBLOCK); 60169570cc8Sopenharmony_ci APPSPAWN_CHECK(pfd >= 0, return -1, "Failed open pty err=%{public}d", errno); 60269570cc8Sopenharmony_ci APPSPAWN_CHECK(grantpt(pfd) >= 0, close(pfd); return -1, "Failed to call grantpt"); 60369570cc8Sopenharmony_ci APPSPAWN_CHECK(unlockpt(pfd) >= 0, close(pfd); return -1, "Failed to call unlockpt"); 60469570cc8Sopenharmony_ci char ptsbuffer[PTY_PATH_SIZE] = {0}; 60569570cc8Sopenharmony_ci int ret = ptsname_r(pfd, ptsbuffer, sizeof(ptsbuffer)); 60669570cc8Sopenharmony_ci APPSPAWN_CHECK(ret >= 0, close(pfd); 60769570cc8Sopenharmony_ci return -1, "Failed to get pts name err=%{public}d", errno); 60869570cc8Sopenharmony_ci APPSPAWN_LOGI("ptsbuffer is %{public}s", ptsbuffer); 60969570cc8Sopenharmony_ci APPSPAWN_CHECK(chmod(ptsbuffer, S_IRWXU | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) == 0, close(pfd); 61069570cc8Sopenharmony_ci return -1, "Failed to chmod %{public}s, err=%{public}d", ptsbuffer, errno); 61169570cc8Sopenharmony_ci ptyFd_ = pfd; 61269570cc8Sopenharmony_ci ptyName_ = std::string(ptsbuffer); 61369570cc8Sopenharmony_ci return 0; 61469570cc8Sopenharmony_ci} 61569570cc8Sopenharmony_ci} // namespace AppSpawnModuleTest 61669570cc8Sopenharmony_ci} // namespace OHOS 617