| 71 | int ProcessExecutor::GetExitValue() { return this->m_ExitValue; }; |
| 72 | |
| 73 | bool ProcessExecutor::Execute(const std::string &executionPath, const ArgumentListType &argumentList) |
| 74 | { |
| 75 | std::vector<const char*> pArguments_(argumentList.size() + 1); |
| 76 | |
| 77 | for (ArgumentListType::size_type index = 0; index < argumentList.size(); ++index) |
| 78 | { |
| 79 | pArguments_[index] = argumentList[index].c_str(); |
| 80 | } |
| 81 | pArguments_.push_back(nullptr); //terminating null element as required by ITK |
| 82 | |
| 83 | bool normalExit = false; |
| 84 | |
| 85 | try |
| 86 | { |
| 87 | m_ProcessID = itksysProcess_New(); |
| 88 | itksysProcess_SetCommand(m_ProcessID, pArguments_.data()); |
| 89 | |
| 90 | /* Place the process in a new process group for seamless interruption when required. */ |
| 91 | itksysProcess_SetOption(m_ProcessID, itksysProcess_Option_CreateProcessGroup, 1); |
| 92 | |
| 93 | itksysProcess_SetWorkingDirectory(m_ProcessID, executionPath.c_str()); |
| 94 | |
| 95 | if (this->m_SharedOutputPipes) |
| 96 | { |
| 97 | itksysProcess_SetPipeShared(m_ProcessID, itksysProcess_Pipe_STDOUT, 1); |
| 98 | itksysProcess_SetPipeShared(m_ProcessID, itksysProcess_Pipe_STDERR, 1); |
| 99 | } |
| 100 | |
| 101 | itksysProcess_Execute(m_ProcessID); |
| 102 | |
| 103 | char *rawOutput = nullptr; |
| 104 | int outputLength = 0; |
| 105 | while (true) |
| 106 | { |
| 107 | int dataStatus = itksysProcess_WaitForData(m_ProcessID, &rawOutput, &outputLength, nullptr); |
| 108 | |
| 109 | if (dataStatus == itksysProcess_Pipe_STDOUT) |
| 110 | { |
| 111 | std::string data(rawOutput, outputLength); |
| 112 | this->InvokeEvent(ExternalProcessStdOutEvent(data)); |
| 113 | } |
| 114 | else if (dataStatus == itksysProcess_Pipe_STDERR) |
| 115 | { |
| 116 | std::string data(rawOutput, outputLength); |
| 117 | this->InvokeEvent(ExternalProcessStdErrEvent(data)); |
| 118 | } |
| 119 | else |
| 120 | { |
| 121 | break; |
| 122 | } |
| 123 | } |
| 124 | |
| 125 | itksysProcess_WaitForExit(m_ProcessID, nullptr); |
| 126 | |
| 127 | auto state = static_cast<itksysProcess_State_e>(itksysProcess_GetState(m_ProcessID)); |
| 128 | |
| 129 | normalExit = (state == itksysProcess_State_Exited); |
| 130 | this->m_ExitValue = itksysProcess_GetExitValue(m_ProcessID); |