|
|
@@ -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;
|
|
|
}
|
|
|
}
|
|
|
|