| 202 | } |
| 203 | |
| 204 | bool cmUVReadOnlyProcess::start(uv_loop_t* uv_loop, |
| 205 | std::function<void()> finishedCallback) |
| 206 | { |
| 207 | if (this->IsStarted() || !this->Result()) { |
| 208 | return false; |
| 209 | } |
| 210 | |
| 211 | // Reset result before the start |
| 212 | this->Result()->reset(); |
| 213 | |
| 214 | // Fill command string pointers |
| 215 | if (!this->Setup().Command.empty()) { |
| 216 | this->CommandPtr_.reserve(this->Setup().Command.size() + 1); |
| 217 | for (std::string const& arg : this->Setup().Command) { |
| 218 | this->CommandPtr_.push_back(arg.c_str()); |
| 219 | } |
| 220 | this->CommandPtr_.push_back(nullptr); |
| 221 | } else { |
| 222 | this->Result()->ErrorMessage = "Empty command"; |
| 223 | } |
| 224 | |
| 225 | if (!this->Result()->error()) { |
| 226 | if (!this->UVPipeOut_.init(uv_loop)) { |
| 227 | this->Result()->ErrorMessage = "libuv stdout pipe initialization failed"; |
| 228 | } |
| 229 | } |
| 230 | if (!this->Result()->error()) { |
| 231 | if (!this->UVPipeErr_.init(uv_loop)) { |
| 232 | this->Result()->ErrorMessage = "libuv stderr pipe initialization failed"; |
| 233 | } |
| 234 | } |
| 235 | if (!this->Result()->error()) { |
| 236 | // -- Setup process stdio options |
| 237 | // stdin |
| 238 | this->UVOptionsStdIO_[0].flags = UV_IGNORE; |
| 239 | this->UVOptionsStdIO_[0].data.stream = nullptr; |
| 240 | // stdout |
| 241 | this->UVOptionsStdIO_[1].flags = |
| 242 | static_cast<uv_stdio_flags>(UV_CREATE_PIPE | UV_WRITABLE_PIPE); |
| 243 | this->UVOptionsStdIO_[1].data.stream = this->UVPipeOut_.uv_stream(); |
| 244 | // stderr |
| 245 | this->UVOptionsStdIO_[2].flags = |
| 246 | static_cast<uv_stdio_flags>(UV_CREATE_PIPE | UV_WRITABLE_PIPE); |
| 247 | this->UVOptionsStdIO_[2].data.stream = this->UVPipeErr_.uv_stream(); |
| 248 | |
| 249 | // -- Setup process options |
| 250 | std::fill_n(reinterpret_cast<char*>(&this->UVOptions_), |
| 251 | sizeof(this->UVOptions_), 0); |
| 252 | this->UVOptions_.exit_cb = &cmUVReadOnlyProcess::UVExit; |
| 253 | this->UVOptions_.file = this->CommandPtr_[0]; |
| 254 | this->UVOptions_.args = const_cast<char**>(this->CommandPtr_.data()); |
| 255 | this->UVOptions_.cwd = this->Setup_.WorkingDirectory.c_str(); |
| 256 | this->UVOptions_.flags = UV_PROCESS_WINDOWS_HIDE; |
| 257 | #if UV_VERSION_MAJOR > 1 || !defined(CMAKE_USE_SYSTEM_LIBUV) |
| 258 | this->UVOptions_.flags |= UV_PROCESS_WINDOWS_USE_PARENT_ERROR_MODE; |
| 259 | #endif |
| 260 | this->UVOptions_.stdio_count = |
| 261 | static_cast<int>(this->UVOptionsStdIO_.size()); |