summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorAsit Dhal <dhal.asitk@gmail.com>2020-12-08 08:51:00 (GMT)
committerBrad King <brad.king@kitware.com>2020-12-10 11:09:59 (GMT)
commite5a4ffaad166de7a8b907919ca2d805a3ec72c39 (patch)
treedc88ffe172348ecb4a33cd3a206ba18964942c4e /Source
parent8a3ecb484fb04aa9fb8b9f6d198b3a6942c26115 (diff)
downloadCMake-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.cxx118
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;
}
}