From 60068693f0f9bb07349e6e551cacdce561560064 Mon Sep 17 00:00:00 2001 From: liduo Date: Fri, 27 Jun 2025 14:40:51 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E6=9B=BF=E6=8D=A2popen=E4=B8=BA=E6=9B=B4?= =?UTF-8?q?=E5=AE=89=E5=85=A8=E7=9A=84=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: liduo --- include/restool_errors.h | 1 + src/restool_errors.cpp | 133 +++++++++++++++++++++++++++++++++------ 2 files changed, 116 insertions(+), 18 deletions(-) diff --git a/include/restool_errors.h b/include/restool_errors.h index 3bcb79d..b218903 100644 --- a/include/restool_errors.h +++ b/include/restool_errors.h @@ -29,6 +29,7 @@ namespace Restool { constexpr uint32_t RESTOOL_SUCCESS = 0; constexpr uint32_t RESTOOL_ERROR = -1; constexpr uint16_t BUFFER_SIZE = 4096; +constexpr uint16_t BUFFER_SIZE_SMALL = 128; const std::string ERROR_MORE_INFO_FILE = "restool_faq.json"; // 11200xxx unknown error constexpr uint32_t ERR_CODE_UNDEFINED_ERROR = 11200000; diff --git a/src/restool_errors.cpp b/src/restool_errors.cpp index e3e63d8..35d7e78 100644 --- a/src/restool_errors.cpp +++ b/src/restool_errors.cpp @@ -15,6 +15,13 @@ #include #include +#ifdef __WIN32 +#include +#else +#include +#include +#include +#endif #include "resource_util.h" #include "restool_errors.h" @@ -525,33 +532,132 @@ const std::map ERRORS_MAP = { #ifdef __WIN32 constexpr int WIN_LOCALE_CN = 2052; #endif +const std::string LOCALE_CMD_WIN = "wmic os get locale"; +const std::string LOCALE_CMD_LINUX = "locale"; +const std::string LOCALE_CMD_MAC = "defaults read -globalDomain AppleLocale"; const std::string LOCALE_CN = "zh_CN"; std::map faqInfos; MoreInfo defaultMoreInfo = {}; Language osLanguage = Language::EN; +bool IsValidCmd(const std::string &cmd) +{ + if (cmd == LOCALE_CMD_WIN || cmd == LOCALE_CMD_LINUX || cmd == LOCALE_CMD_MAC) { + return true; + } + return false; +} + +#ifdef __WIN32 std::string ExecuteCommand(const std::string &cmd) { + if (!IsValidCmd(cmd)) { + return ""; + } + SECURITY_ATTRIBUTES saAttr; + saAttr.nLength = sizeof(SECURITY_ATTRIBUTES); + saAttr.bInheritHandle = TRUE; + saAttr.lpSecurityDescriptor = NULL; + HANDLE hReadPipe; + HANDLE hWritePipe; + if (!CreatePipe(&hReadPipe, &hWritePipe, &saAttr, 0)) { + return "CreatePipe failed"; + } + STARTUPINFO si; + PROCESS_INFORMATION pi; + ZeroMemory(&si, sizeof(si)); + si.cb = sizeof(si); + si.hStdError = hWritePipe; + si.hStdOutput = hWritePipe; + si.hStdInput = GetStdHandle(STD_INPUT_HANDLE); + si.dwFlags |= STARTF_USESTDHANDLES; + ZeroMemory(&pi, sizeof(pi)); + + if (!CreateProcess(NULL, const_cast(cmd.c_str()), NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) { + CloseHandle(hReadPipe); + CloseHandle(hWritePipe); + return "CreateProcess failed"; + } + // close the write end of the pipe in the parent process + CloseHandle(hWritePipe); std::string result; - FILE *pipe = popen(cmd.c_str(), "r"); - if (!pipe) { + DWORD bytesRead; + CHAR buffer[BUFFER_SIZE_SMALL]; + while (ReadFile(hReadPipe, buffer, sizeof(buffer) - 1, &bytesRead, NULL) && bytesRead != 0) { + buffer[bytesRead] = '\0'; + result += buffer; + } + WaitForSingleObject(pi.hProcess, INFINITE); + CloseHandle(hReadPipe); + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + return result; +} +#else +std::vector split(const std::string &s, const char &delimiter) +{ + std::vector tokens; + std::string token; + std::stringstream tokenStream(s); + while (std::getline(tokenStream, token, delimiter)) { tokens.push_back(token); } + return tokens; +} + +std::string ExecuteCommand(const std::string &cmd) +{ + std::string result; + if (!IsValidCmd(cmd)) { return result; } - char buffer[BUFFER_SIZE]; - while (!feof(pipe)) { - if (fgets(buffer, BUFFER_SIZE, pipe) != NULL) { + int pipefd[2]; + pid_t pid; + if (pipe(pipefd) == -1) { + perror("open pipe failed"); + return result; + } + pid = fork(); + if (pid == -1) { + perror("fork failed"); + return result; + } + if (pid == 0) { + // child process + close(pipefd[0]); + dup2(pipefd[1], STDOUT_FILENO); + close(pipefd[1]); + std::vector cmds = split(cmd, ' '); + char *argv[cmds.size() + 1]; + size_t i = 0; + for (i = 0; i < cmds.size(); ++i) { + argv[i] = cmds[i].data(); + } + argv[i] = nullptr; + execvp(argv[0], argv); + // if execvp returns, there was an error. + perror("execle failed"); + exit(EXIT_FAILURE); + } else { + // parent process + // close unused write end + close(pipefd[1]); + char buffer[BUFFER_SIZE_SMALL]; + ssize_t readBytes; + while ((readBytes = read(pipefd[0], buffer, sizeof(buffer) - 1)) > 0) { + buffer[readBytes] = '\0'; result += buffer; } + close(pipefd[0]); + wait(nullptr); } - pclose(pipe); return result; } +#endif #ifdef __WIN32 Language GetWinLanguage() { - std::string result = ExecuteCommand("wmic os get locale"); + std::string result = ExecuteCommand(LOCALE_CMD_WIN); size_t pos = 0; std::string locale = "Locale"; if ((pos = result.find(locale)) != std::string::npos) { @@ -574,18 +680,9 @@ Language GetWinLanguage() #endif #ifdef __LINUX__ -std::vector split(const std::string &s, const char &delimiter) -{ - std::vector tokens; - std::string token; - std::stringstream tokenStream(s); - while (std::getline(tokenStream, token, delimiter)) { tokens.push_back(token); } - return tokens; -} - Language GetLinuxLanguage() { - std::string result = ExecuteCommand("locale"); + std::string result = ExecuteCommand(LOCALE_CMD_LINUX); if (result.empty()) { return Language::CN; } @@ -609,7 +706,7 @@ Language GetLinuxLanguage() #ifdef __MAC__ Language GetMacLanguage() { - std::string result = ExecuteCommand("defaults read -globalDomain AppleLocale"); + std::string result = ExecuteCommand(LOCALE_CMD_MAC); if (result.empty()) { return Language::CN; } -- Gitee From b5b54c94140951dd228104f91c603af07a6bc392 Mon Sep 17 00:00:00 2001 From: sunjie Date: Wed, 2 Jul 2025 09:25:19 +0800 Subject: [PATCH 2/3] =?UTF-8?q?fix=20id=20=E6=BA=A2=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: sunjie Change-Id: I59e1259aaddc49b5f40f44bedca0bbdacc6a7a6f --- include/resource_dumper.h | 2 +- src/resource_dumper.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/resource_dumper.h b/include/resource_dumper.h index 327a75b..9799c6b 100644 --- a/include/resource_dumper.h +++ b/include/resource_dumper.h @@ -66,7 +66,7 @@ private: uint32_t AddPairVauleToJson(const ResourceItem &item, cJSON *json) const; uint32_t AddKeyParamsToJson(const std::vector &keyParams, cJSON *json) const; uint32_t AddResourceToJson(int64_t id, const std::vector &items, cJSON *json) const; - uint32_t AddItemCommonPropToJson(int32_t resId, const ResourceItem &item, cJSON* json) const; + uint32_t AddItemCommonPropToJson(int64_t resId, const ResourceItem &item, cJSON* json) const; }; } // namespace Restool diff --git a/src/resource_dumper.cpp b/src/resource_dumper.cpp index 7cb3b0a..4778129 100644 --- a/src/resource_dumper.cpp +++ b/src/resource_dumper.cpp @@ -194,7 +194,7 @@ uint32_t CommonDumper::AddKeyParamsToJson(const std::vector &keyParams return RESTOOL_SUCCESS; } -uint32_t CommonDumper::AddItemCommonPropToJson(int32_t resId, const ResourceItem &item, cJSON* json) const +uint32_t CommonDumper::AddItemCommonPropToJson(int64_t resId, const ResourceItem &item, cJSON* json) const { if (!json) { PrintError(GetError(ERR_CODE_UNDEFINED_ERROR).FormatCause("add item common property to null json object")); -- Gitee From cf5b75a1f0f384a39f3eb3a89723d4253536acc0 Mon Sep 17 00:00:00 2001 From: liduo Date: Wed, 2 Jul 2025 21:43:25 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E7=BC=96=E7=A0=81=E8=A7=84=E8=8C=83?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=A6=81=E6=AD=A2=E4=BD=BF=E7=94=A8exit?= =?UTF-8?q?=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: liduo --- src/restool.cpp | 6 +++++- src/restool_errors.cpp | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/restool.cpp b/src/restool.cpp index dfe9ae0..4aab32f 100644 --- a/src/restool.cpp +++ b/src/restool.cpp @@ -30,7 +30,11 @@ int main(int argc, char *argv[]) PrintError(GetError(ERR_CODE_UNKNOWN_COMMAND_ERROR).FormatCause("argv null")); return RESTOOL_ERROR; } - InitFaq(std::string(argv[0])); + try { + InitFaq(std::string(argv[0])); + } catch (const std::runtime_error &error) { + return RESTOOL_ERROR; + } auto &parser = CmdParser::GetInstance(); return parser.Parse(argc, argv, 1); } diff --git a/src/restool_errors.cpp b/src/restool_errors.cpp index 35d7e78..bcb572c 100644 --- a/src/restool_errors.cpp +++ b/src/restool_errors.cpp @@ -635,8 +635,8 @@ std::string ExecuteCommand(const std::string &cmd) argv[i] = nullptr; execvp(argv[0], argv); // if execvp returns, there was an error. - perror("execle failed"); - exit(EXIT_FAILURE); + perror("execvp failed"); + throw std::runtime_error("execvp failed"); } else { // parent process // close unused write end -- Gitee