| 444 | } |
| 445 | |
| 446 | inline static void* WriteStream(void* data) noexcept { |
| 447 | TPipePump* pump = reinterpret_cast<TPipePump*>(data); |
| 448 | try { |
| 449 | int bytes = 0; |
| 450 | int bytesToWrite = 0; |
| 451 | char* bufPos = nullptr; |
| 452 | TBuffer buffer(DATA_BUFFER_SIZE); |
| 453 | |
| 454 | while (true) { |
| 455 | if (!bytesToWrite) { |
| 456 | bytesToWrite = pump->InputStream->Read(buffer.Data(), buffer.Capacity()); |
| 457 | if (bytesToWrite == 0) { |
| 458 | if (pump->ShouldClosePipe->load(std::memory_order_acquire)) { |
| 459 | break; |
| 460 | } |
| 461 | continue; |
| 462 | } |
| 463 | bufPos = buffer.Data(); |
| 464 | } |
| 465 | |
| 466 | bytes = pump->Pipe->Write(bufPos, bytesToWrite); |
| 467 | if (bytes > 0) { |
| 468 | bytesToWrite -= bytes; |
| 469 | bufPos += bytes; |
| 470 | } else { |
| 471 | break; |
| 472 | } |
| 473 | } |
| 474 | if (pump->Pipe->IsOpen()) { |
| 475 | pump->Pipe->Close(); |
| 476 | } |
| 477 | } catch (...) { |
| 478 | pump->InternalError = CurrentExceptionMessage(); |
| 479 | } |
| 480 | return nullptr; |
| 481 | } |
| 482 | |
| 483 | TString GetQuotedCommand() const; |
| 484 | }; |