diff options
author | Asit Dhal <dhal.asitk@gmail.com> | 2020-12-08 08:51:00 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2020-12-10 11:09:59 (GMT) |
commit | e5a4ffaad166de7a8b907919ca2d805a3ec72c39 (patch) | |
tree | dc88ffe172348ecb4a33cd3a206ba18964942c4e /Source | |
parent | 8a3ecb484fb04aa9fb8b9f6d198b3a6942c26115 (diff) | |
download | CMake-e5a4ffaad166de7a8b907919ca2d805a3ec72c39.zip CMake-e5a4ffaad166de7a8b907919ca2d805a3ec72c39.tar.gz CMake-e5a4ffaad166de7a8b907919ca2d805a3ec72c39.tar.bz2 |
execute_process: Improve COMMAND_ERROR_IS_FATAL error capture scenarios
1. COMMAND_ERROR_IS_FATAL ANY will capture errors if the exit code is
non zero, there is a timeout or an abnormal exit.
2. COMMAND_ERROR_IS_FATAL LAST
will capture if only the last process has an exit code non zero, there
is a timeout or an abnormal exit.
Fixes: #21562
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmExecuteProcessCommand.cxx | 118 |
1 files changed, 87 insertions, 31 deletions
diff --git a/Source/cmExecuteProcessCommand.cxx b/Source/cmExecuteProcessCommand.cxx index 14147e0..5a85b7d 100644 --- a/Source/cmExecuteProcessCommand.cxx +++ b/Source/cmExecuteProcessCommand.cxx @@ -6,8 +6,10 @@ #include <cctype> /* isspace */ #include <cstdio> #include <iostream> +#include <map> #include <memory> #include <sstream> +#include <utility> #include <vector> #include <cm/string_view> @@ -375,47 +377,101 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args, } } - if (arguments.CommandErrorIsFatal == "ANY"_s) { - if (cmsysProcess_GetState(cp) == cmsysProcess_State_Exited) { - std::vector<int> failedIndexes; - for (int i = 0; i < static_cast<int>(arguments.Commands.size()); ++i) { - if (cmsysProcess_GetStateByIndex(cp, i) == - kwsysProcess_StateByIndex_Exited) { - int exitCode = cmsysProcess_GetExitValueByIndex(cp, i); - if (exitCode) { - failedIndexes.push_back(i); - } + auto queryProcessStatusByIndex = [&cp](int index) -> std::string { + std::string processStatus; + switch (cmsysProcess_GetStateByIndex(cp, static_cast<int>(index))) { + case kwsysProcess_StateByIndex_Exited: { + int exitCode = cmsysProcess_GetExitValueByIndex(cp, index); + if (exitCode) { + processStatus = "Child return code: " + std::to_string(exitCode); } + } break; + case kwsysProcess_StateByIndex_Exception: { + processStatus = cmStrCat( + "Abnormal exit with child return code: ", + cmsysProcess_GetExceptionStringByIndex(cp, static_cast<int>(index))); + break; } - if (!failedIndexes.empty()) { - std::ostringstream oss; - oss << "failed command indexes: "; - for (auto i = 0u; i < failedIndexes.size(); i++) { - if (i == failedIndexes.size() - 1) { - oss << failedIndexes[i] + 1; - } else { - oss << failedIndexes[i] + 1 << ", "; + case kwsysProcess_StateByIndex_Error: + default: + processStatus = "Error getting the child return code"; + break; + } + return processStatus; + }; + + if (arguments.CommandErrorIsFatal == "ANY"_s) { + bool ret = true; + switch (cmsysProcess_GetState(cp)) { + case cmsysProcess_State_Exited: { + std::map<int, std::string> failureIndices; + for (int i = 0; i < static_cast<int>(arguments.Commands.size()); ++i) { + std::string processStatus = queryProcessStatusByIndex(i); + if (!processStatus.empty()) { + failureIndices[i] = processStatus; + } + if (!failureIndices.empty()) { + std::ostringstream oss; + oss << "failed command indexes:\n"; + for (auto const& e : failureIndices) { + oss << " " << e.first + 1 << ": \"" << e.second << "\"\n"; + } + status.SetError(oss.str()); + ret = false; } } - status.SetError(oss.str()); - cmSystemTools::SetFatalErrorOccured(); - return false; - } + } break; + case cmsysProcess_State_Exception: + status.SetError( + cmStrCat("abnormal exit: ", cmsysProcess_GetExceptionString(cp))); + ret = false; + break; + case cmsysProcess_State_Error: + status.SetError(cmStrCat("error getting child return code: ", + cmsysProcess_GetErrorString(cp))); + ret = false; + break; + case cmsysProcess_State_Expired: + status.SetError("Process terminated due to timeout"); + ret = false; + break; + } + + if (!ret) { + cmSystemTools::SetFatalErrorOccured(); + return false; } } if (arguments.CommandErrorIsFatal == "LAST"_s) { - if (cmsysProcess_GetState(cp) == cmsysProcess_State_Exited) { - int lastIndex = static_cast<int>(arguments.Commands.size() - 1); - if (cmsysProcess_GetStateByIndex(cp, lastIndex) == - kwsysProcess_StateByIndex_Exited) { - int exitCode = cmsysProcess_GetExitValueByIndex(cp, lastIndex); - if (exitCode) { + bool ret = true; + switch (cmsysProcess_GetState(cp)) { + case cmsysProcess_State_Exited: { + int lastIndex = static_cast<int>(arguments.Commands.size() - 1); + const std::string processStatus = queryProcessStatusByIndex(lastIndex); + if (!processStatus.empty()) { status.SetError("last command failed"); - cmSystemTools::SetFatalErrorOccured(); - return false; + ret = false; } - } + } break; + case cmsysProcess_State_Exception: + status.SetError( + cmStrCat("Abnormal exit: ", cmsysProcess_GetExceptionString(cp))); + ret = false; + break; + case cmsysProcess_State_Error: + status.SetError(cmStrCat("Error getting child return code: ", + cmsysProcess_GetErrorString(cp))); + ret = false; + break; + case cmsysProcess_State_Expired: + status.SetError("Process terminated due to timeout"); + ret = false; + break; + } + if (!ret) { + cmSystemTools::SetFatalErrorOccured(); + return false; } } |