| 845 | } |
| 846 | |
| 847 | void TShellCommand::TImpl::Communicate(TProcessInfo* pi) { |
| 848 | THolder<IOutputStream> outputHolder; |
| 849 | IOutputStream* output = pi->Parent->Options_.OutputStream; |
| 850 | if (!output) { |
| 851 | outputHolder.Reset(output = new TStringOutput(pi->Parent->CollectedOutput)); |
| 852 | } |
| 853 | |
| 854 | THolder<IOutputStream> errorHolder; |
| 855 | IOutputStream* error = pi->Parent->Options_.ErrorStream; |
| 856 | if (!error) { |
| 857 | errorHolder.Reset(error = new TStringOutput(pi->Parent->CollectedError)); |
| 858 | } |
| 859 | |
| 860 | IInputStream*& input = pi->Parent->Options_.InputStream; |
| 861 | |
| 862 | #if defined(_unix_) |
| 863 | // not really needed, io is done via poll |
| 864 | if (pi->OutputFd.IsOpen()) { |
| 865 | SetNonBlock(pi->OutputFd); |
| 866 | } |
| 867 | if (pi->ErrorFd.IsOpen()) { |
| 868 | SetNonBlock(pi->ErrorFd); |
| 869 | } |
| 870 | if (pi->InputFd.IsOpen()) { |
| 871 | SetNonBlock(pi->InputFd); |
| 872 | } |
| 873 | #endif |
| 874 | |
| 875 | try { |
| 876 | #if defined(_win_) |
| 877 | TPipePump pumps[3] = {0}; |
| 878 | pumps[0] = {&pi->ErrorFd, error}; |
| 879 | pumps[1] = {&pi->OutputFd, output}; |
| 880 | |
| 881 | TVector<THolder<TThread>> streamThreads; |
| 882 | streamThreads.emplace_back(new TThread(&TImpl::ReadStream, &pumps[0])); |
| 883 | streamThreads.emplace_back(new TThread(&TImpl::ReadStream, &pumps[1])); |
| 884 | |
| 885 | if (input) { |
| 886 | pumps[2] = {&pi->InputFd, nullptr, input, &pi->Parent->Options_.ShouldCloseInput}; |
| 887 | streamThreads.emplace_back(new TThread(&TImpl::WriteStream, &pumps[2])); |
| 888 | } |
| 889 | |
| 890 | for (auto& threadHolder : streamThreads) { |
| 891 | threadHolder->Start(); |
| 892 | } |
| 893 | #else |
| 894 | TBuffer buffer(DATA_BUFFER_SIZE); |
| 895 | TBuffer inputBuffer(DATA_BUFFER_SIZE); |
| 896 | int bytes; |
| 897 | int bytesToWrite = 0; |
| 898 | char* bufPos = nullptr; |
| 899 | #endif |
| 900 | TWaitResult waitPidResult; |
| 901 | TExitStatus status = 0; |
| 902 | |
| 903 | while (true) { |
| 904 | { |
nothing calls this directly
no test coverage detected