1/* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15#include <stdio.h> 16#include <stdlib.h> 17#include <signal.h> 18 19#include "appspawn.h" 20#include "appspawn_utils.h" 21 22#include "devicedebug_base.h" 23#include "devicedebug_kill.h" 24#include "cJSON.h" 25 26#ifdef __cplusplus 27extern "C" { 28#endif 29 30#define DEVICEDEBUG_KILL_CMD_NUM 4 31#define DEVICEDEBUG_KILL_CMD_SIGNAL_INDEX 2 32#define DEVICEDEBUG_KILL_CMD_PID_INDEX 3 33 34APPSPAWN_STATIC void DeviceDebugShowKillHelp(void) 35{ 36 printf("\r\nusage: devicedebug kill [options] <pid>" 37 "\r\noptions list:" 38 "\r\n -h, --help list available commands" 39 "\r\n kill -<signal> <pid> send a signal to a process\r\n"); 40} 41 42APPSPAWN_STATIC char* DeviceDebugJsonStringGeneral(int pid, const char *op, cJSON *args) 43{ 44 cJSON *root = cJSON_CreateObject(); 45 if (root == NULL) { 46 DEVICEDEBUG_LOGE("devicedebug json write create root object unsuccess"); 47 return NULL; 48 } 49 50 cJSON_AddNumberToObject(root, "app", pid); 51 cJSON_AddStringToObject(root, "op", op); 52 cJSON_AddItemToObject(root, "args", args); 53 54 char *jsonString = cJSON_Print(root); 55 cJSON_Delete(root); 56 return jsonString; 57} 58 59APPSPAWN_STATIC int DeviceDebugKill(int pid, int signal) 60{ 61 AppSpawnClientHandle clientHandle; 62 int ret = AppSpawnClientInit(APPSPAWN_SERVER_NAME, &clientHandle); 63 if (ret != 0) { 64 DEVICEDEBUG_LOGE("devicedebug appspawn client init unsuccess, ret=%{public}d", ret); 65 return ret; 66 } 67 68 AppSpawnReqMsgHandle reqHandle; 69 ret = AppSpawnReqMsgCreate(MSG_DEVICE_DEBUG, "devicedebug", &reqHandle); 70 if (ret != 0) { 71 DEVICEDEBUG_LOGE("devicedebug appspawn message create unsuccess, ret=%{public}d", ret); 72 return ret; 73 } 74 75 cJSON *args = cJSON_CreateObject(); 76 if (args == NULL) { 77 DEVICEDEBUG_LOGE("devicedebug json write create args object unsuccess"); 78 return DEVICEDEBUG_ERRNO_JSON_CREATED_FAILED; 79 } 80 cJSON_AddNumberToObject(args, "signal", signal); 81 char *jsonString = DeviceDebugJsonStringGeneral(pid, "kill", args); 82 if (jsonString == NULL) { 83 cJSON_Delete(args); 84 return DEVICEDEBUG_ERRNO_JSON_CREATED_FAILED; 85 } 86 87 ret = AppSpawnReqMsgAddExtInfo(reqHandle, "devicedebug", (uint8_t *)jsonString, strlen(jsonString) + 1); 88 if (ret != 0) { 89 DEVICEDEBUG_LOGE("devicedebug appspawn message add devicedebug[%{public}s] unsuccess, ret=%{public}d", 90 jsonString, ret); 91 return ret; 92 } 93 94 AppSpawnResult result = {0}; 95 ret = AppSpawnClientSendMsg(clientHandle, reqHandle, &result); 96 AppSpawnClientDestroy(clientHandle); 97 if (ret != 0) { 98 DEVICEDEBUG_LOGE("devicedebug appspawn send msg unsuccess, ret=%{public}d", ret); 99 return ret; 100 } 101 102 if (result.result != 0) { 103 DEVICEDEBUG_LOGE("devicedebug appspawn kill process unsuccess, result=%{public}d", result.result); 104 return result.result; 105 } 106 107 return 0; 108} 109 110int DeviceDebugCmdKill(int argc, char *argv[]) 111{ 112 if (!IsDeveloperModeOpen()) { 113 return DEVICEDEBUG_ERRNO_NOT_IN_DEVELOPER_MODE; 114 } 115 116 if (argc <= DEVICEDEBUG_NUM_2 || strcmp(argv[DEVICEDEBUG_NUM_2], "-h") == 0 || 117 strcmp(argv[DEVICEDEBUG_NUM_2], "help") == 0) { 118 DeviceDebugShowKillHelp(); 119 return 0; 120 } 121 122 if (argc < DEVICEDEBUG_KILL_CMD_NUM) { 123 DEVICEDEBUG_LOGE("devicedebug cmd operator num is %{public}d < %{public}d", argc, DEVICEDEBUG_KILL_CMD_NUM); 124 DeviceDebugShowKillHelp(); 125 return DEVICEDEBUG_ERRNO_OPERATOR_ARGV_MISS; 126 } 127 128 int signal = atoi(argv[DEVICEDEBUG_KILL_CMD_SIGNAL_INDEX] + 1); 129 if (signal > SIGRTMAX || signal <= 0) { 130 DEVICEDEBUG_LOGE("signal is %{public}d > %{public}d", signal, SIGRTMAX); 131 DeviceDebugShowKillHelp(); 132 return DEVICEDEBUG_ERRNO_PARAM_INVALID; 133 } 134 135 int pid = atoi(argv[DEVICEDEBUG_KILL_CMD_PID_INDEX]); 136 DEVICEDEBUG_LOGI("devicedebug cmd kill start signal[%{public}d], pid[%{public}d]", signal, pid); 137 138 return DeviceDebugKill(pid, signal); 139} 140 141#ifdef __cplusplus 142} 143#endif 144