diff --git a/host/smartperf/client/client_command/include/sp_utils.h b/host/smartperf/client/client_command/include/sp_utils.h index 3e3a571728d18e9d6a2b883278bef013b01390be..8e41e889549c74a9a74ee769d02ba8b9e8c9c776 100644 --- a/host/smartperf/client/client_command/include/sp_utils.h +++ b/host/smartperf/client/client_command/include/sp_utils.h @@ -170,6 +170,8 @@ size_t GetFileSize(std::string filePath); bool IsFindDHGame(const std::string &pkg); std::string GetSurface(); std::string GetProductName(); +std::string EscapeShellArgs(const std::string& args); +bool IsInvalidPkgName(const std::string& pkgName); }; } } diff --git a/host/smartperf/client/client_command/include/startup_delay.h b/host/smartperf/client/client_command/include/startup_delay.h index 511c484f98d515097c6fca8ef817414ccb3b4c03..a14782eb27b477654dabe70274de97f9ff07797a 100644 --- a/host/smartperf/client/client_command/include/startup_delay.h +++ b/host/smartperf/client/client_command/include/startup_delay.h @@ -17,6 +17,12 @@ #include namespace OHOS { namespace SmartPerf { +enum ErrorSpCode { + DATA_IS_EMPTY = 100001, + INVALID_PKG_NAME = 100002, + FILE_OPEN_IS_NULL = 100003, + FILE_CLOSE_FAILED = 100004, +}; class StartUpDelay { public: StartUpDelay(); @@ -24,13 +30,14 @@ public: void GetTrace(const std::string &traceName) const; void GetHisysIdAndKill() const; void GetHisysId() const; - std::string GetPidByPkg(const std::string &curPkgName, std::string* pids = nullptr) const; + std::string GetPidByPkg(const std::string &curPkgName, std::string* pids = nullptr); bool KillSpProcess() const; bool GetSpClear(bool isKillTestServer) const; void ClearOldServer() const; - std::string ExecuteCommand(const std::vector &args) const; std::vector GetPidParams() const; void KillTestSpdaemon(const std::string &line, const std::string &curPid) const; + std::string GetAppInforByPs(const std::string& curPkgName); + std::vector> GetAppProcInfor(const std::string& curPkgName); }; } } diff --git a/host/smartperf/client/client_command/include/task_manager.h b/host/smartperf/client/client_command/include/task_manager.h index b6d6a743d5fe781501f8370cb89de5326ec3c8f3..15715c956a7046e9dd95187bf0be2ed497723923 100644 --- a/host/smartperf/client/client_command/include/task_manager.h +++ b/host/smartperf/client/client_command/include/task_manager.h @@ -86,6 +86,7 @@ private: std::condition_variable finishCond_; std::mutex finishMtx_; std::string processName_; + std::string mainProcessId_; std::string processIds_; bool printDataInfo_ {true}; bool ipcDataRecv_ {false}; diff --git a/host/smartperf/client/client_command/sp_utils.cpp b/host/smartperf/client/client_command/sp_utils.cpp index 29f10195a131c340d703df7336cb7410d8a5faa3..da8134b1a55b7df6557538fff5decee48b3bdaaa 100644 --- a/host/smartperf/client/client_command/sp_utils.cpp +++ b/host/smartperf/client/client_command/sp_utils.cpp @@ -971,5 +971,31 @@ std::string SPUtils::GetProductName() { return PRODUCT_NAME; } + +std::string SPUtils::EscapeShellArgs(const std::string& args) +{ + std::string escaped; + const size_t expansion = 2; + escaped.reserve(args.size() * expansion); + const char* specicalChars = R"(\\"$`;&|><(){}[]^~*?#!%@ )"; + for (char c : args) { + if (std::strchr(specicalChars, c)) { + escaped += '\\'; + } + escaped += c; + } + LOGD("SPUtils::EscapeShellArgs escaped = (%s)", escaped.c_str()); + return escaped; +} + +bool SPUtils::IsInvalidPkgName(const std::string& pkgName) +{ + if (pkgName.empty() || !isalpha(pkgName[0])) { + return false; + } + return std::all_of(pkgName.begin(), pkgName.end(), [](char c) { + return isalnum(c) || c == '.' || c == '_'; + }); +} } } diff --git a/host/smartperf/client/client_command/startup_delay.cpp b/host/smartperf/client/client_command/startup_delay.cpp index b6f5ff36d05eebdbc5db4e77e803758612ada859..5ac1bbec690f38f2543ddc9c6ba47640e7ac6db5 100644 --- a/host/smartperf/client/client_command/startup_delay.cpp +++ b/host/smartperf/client/client_command/startup_delay.cpp @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include #include #include @@ -31,6 +33,7 @@ namespace OHOS { namespace SmartPerf { +std::string MAIN_PROCESS_ID = ""; std::vector g_pidParams; StartUpDelay::StartUpDelay() {} StartUpDelay::~StartUpDelay() {} @@ -176,77 +179,77 @@ void StartUpDelay::ClearOldServer() const } } } -std::string StartUpDelay::ExecuteCommand(const std::vector &args) const + +std::string StartUpDelay::GetAppInforByPs(const std::string& curPkgName) { - std::string output = ""; - int pipefd[2]; - if (pipe(pipefd) == -1) { - LOGE("startup_delay::Failed to create pipe: %s", strerror(errno)); - return output; - } - pid_t pid = fork(); - if (pid == -1) { - LOGE("startup_delay::Failed to fork: %s", strerror(errno)); - close(pipefd[0]); - close(pipefd[1]); - return output; - } - if (pid == 0) { - close(pipefd[0]); - dup2(pipefd[1], STDOUT_FILENO); - close(pipefd[1]); - if (args.empty() || args[0] == nullptr) { - LOGE("startup_delay::Invalid commd"); - return output; - } - execvp(args[0], const_cast(args.data())); - LOGE("startup_delay::Failed to execute pid: %s", strerror(errno)); - _exit(EXIT_FAILURE); + const std::string pkgName = SPUtils::EscapeShellArgs(curPkgName); + bool isInvalidPkgName = SPUtils::IsInvalidPkgName(pkgName); + if (!isInvalidPkgName) { + return std::to_string(ErrorSpCode::INVALID_PKG_NAME); } - close(pipefd[1]); - char buf[1024]; - ssize_t nread; - while ((nread = read(pipefd[0], buf, sizeof(buf) - 1)) > 0) { - if (nread == sizeof(buf) - 1) { - LOGE("startup_delay::Buffer overflow: %s", strerror(errno)); - break; - } - buf[nread] = '\0'; - output.append(buf); + std::string psCommand = "ps -ef | grep -v grep | grep "; + psCommand += pkgName; + std::vector line(1024); + std::string appProcessInfor; + FILE *fd = popen(command.c_str(), "r"); + if (fd == nullptr) { + return std::to_string(ErrorSpCode::FILE_OPEN_IS_NULL); } - if (nread == -1) { - LOGE("startup_delay::Failed to read from pipe: %s", strerror(errno)); + while (fgets(line.data(), line.size(), fd) != nullptr) { + appProcessInfor += line.data(); } - close(pipefd[0]); - int status; - if (waitpid(pid, &status, 0) == -1) { - LOGE("startup_delay::Failed to wait for child process: %s", strerror(errno)); - return output; + int pcloseResult = pclose(fd); + if (pcloseResult == -1) { + return std::to_string(ErrorSpCode::FILE_CLOSE_FAILED); } - return output; + return appProcessInfor; } -std::string StartUpDelay::GetPidByPkg(const std::string &curPkgName, std::string* pids) const +std::vector> StartUpDelay::GetAppProcInfor(const std::string& curPkgName) { - std::vector args = {"pidof", curPkgName.c_str()}; - args.push_back(nullptr); - std::string resultProcId = ExecuteCommand(args); - LOGD("StartUpDelay::resultProcId(%s)", resultProcId.c_str()); - if (!resultProcId.empty()) { - if (resultProcId.back() == '\n') { - resultProcId.pop_back(); + std::vector> resultAppProcInfor; + const size_t mainProcessPose = 1; + const std::string eachRowOfData = GetAppInforByPs(curPkgName); + if (eachRowOfData.empty()) { + return {{std::to_string(ErrorSpCode::DATA_IS_EMPTY), "Not data found for package"}}; + } + std::istringstream iss(eachRowOfData); + std::string line; + while (std::getline(iss, line)) { + if (line.find("root") != std::string::npos) { + continue; } - g_pidParams.clear(); - SPUtils::StrSplit(resultProcId, " ", g_pidParams); - pids == nullptr ? "" : *pids = resultProcId; - size_t endpos = resultProcId.find(" "); - if (endpos != std::string::npos) { - resultProcId = resultProcId.substr(0, endpos); + std::vector eachRowOfProceInfor; + SPUtils::StrSplit(line, " ", eachRowOfProceInfor); + for (const auto& procName : eachRowOfProceInfor) { + if (procName == curPkgName) { + MAIN_PROCESS_ID = eachRowOfProceInfor[mainProcessPose]; + break; + } } - LOGD("startup_delay::output: (%s) (%s)", resultProcId.c_str(), - pids == nullptr ? resultProcId.c_str() : pids->c_str()); + resultAppProcInfor.push_back(eachRowOfProceInfor); + } + return resultAppProcInfor; +} + +std::string StartUpDelay::GetPidByPkg(const std::string &curPkgName, std::string* pids) +{ + std::vector> resultProceInfor = GetAppProcInfor(curPkgName); + std::string resultChildProcId; + g_pidParams.clear(); + const size_t indexOne = 1; + for (size_t i = 0; i < resultProceInfor.size(); ++i) { + g_pidParams.push_back(resultProceInfor[i][indexOne]); + resultChildProcId += (" " + resultProceInfor[i][indexOne]); + } + if (!resultChildProcId.empty()) { + const size_t firstNonSpace = resultChildProcId.find_first_not_of(" "); + resultChildProcId = resultChildProcId.substr(firstNonSpace); } - return resultProcId; + pids == nullptr ? "" : *pids = resultChildProcId; + LOGD("GetPidByPkg: MAIN_PROCESS_ID = (%s), pids = (%s)", MAIN_PROCESS_ID.c_str(), + pids == nullptr ? resultChildProcId.c_str() : pids->c_str()); + return MAIN_PROCESS_ID; } std::vector StartUpDelay::GetPidParams() const diff --git a/host/smartperf/client/client_command/task_manager.cpp b/host/smartperf/client/client_command/task_manager.cpp index 39432b438444dedd956229d4a2328ff20efd4b55..50261b322b1d44cf2867f0a5b17ff040437fbccb 100644 --- a/host/smartperf/client/client_command/task_manager.cpp +++ b/host/smartperf/client/client_command/task_manager.cpp @@ -435,7 +435,10 @@ void TaskManager::GetProcessInfo(CommandType type, const ArgumentParser::ArgValu if (type == CommandType::CT_PKG) { processName_ = std::get(value); OHOS::SmartPerf::StartUpDelay sp; - sp.GetPidByPkg(processName_, &processIds_); + std::string mainProceId = sp.GetPidByPkg(processName_, &processIds_); + if (!mainProceId.empty()) { + mainProcessId_ = mainProceId; + } } if (type == CommandType::CT_PID) {