@@ -17,7 +17,7 @@ namespace NNet {
1717
1818namespace {
1919
20- [[maybe_unused]] void SetCloseOnExec (int fd) {
20+ void SetCloseOnExec (int fd) {
2121 int flags = fcntl (fd, F_GETFD );
2222 if (flags == -1 ) {
2323 throw std::runtime_error (" fcntl(F_GETFD) failed" );
@@ -70,8 +70,18 @@ void TPipe::TPipeLow::Fork() {
7070 close (pipeStdin[1 ]);
7171 throw std::system_error (code, std::generic_category (), " pipe() failed for stdout" );
7272 }
73+ int pipeStderr[2 ];
74+ if (pipe (pipeStderr) == -1 ) {
75+ auto code = errno;
76+ close (pipeStdin[0 ]);
77+ close (pipeStdin[1 ]);
78+ close (pipeStdout[0 ]);
79+ close (pipeStdout[1 ]);
80+ throw std::system_error (code, std::generic_category (), " pipe() failed for stderr" );
81+ }
7382 SetCloseOnExec (pipeStdin[0 ]); SetCloseOnExec (pipeStdin[1 ]);
7483 SetCloseOnExec (pipeStdout[0 ]); SetCloseOnExec (pipeStdout[1 ]);
84+ SetCloseOnExec (pipeStderr[0 ]); SetCloseOnExec (pipeStderr[1 ]);
7585
7686 auto pid = fork ();
7787 if (pid == -1 ) {
@@ -80,13 +90,16 @@ void TPipe::TPipeLow::Fork() {
8090 close (pipeStdin[1 ]);
8191 close (pipeStdout[0 ]);
8292 close (pipeStdout[1 ]);
93+ close (pipeStderr[0 ]);
94+ close (pipeStderr[1 ]);
8395 throw std::system_error (code, std::generic_category (), " fork() failed" );
8496 }
8597
8698 if (pid == 0 ) {
8799 // Child process
88100 close (pipeStdin[1 ]);
89101 close (pipeStdout[0 ]);
102+ close (pipeStderr[0 ]);
90103
91104 if (dup2 (pipeStdin[0 ], STDIN_FILENO ) == -1 ) {
92105 std::cerr << " dup2() failed for stdin: " << strerror (errno) << std::endl;
@@ -96,9 +109,14 @@ void TPipe::TPipeLow::Fork() {
96109 std::cerr << " dup2() failed for stdout: " << strerror (errno) << std::endl;
97110 _exit (1 );
98111 }
112+ if (dup2 (pipeStderr[1 ], STDERR_FILENO ) == -1 ) {
113+ std::cerr << " dup2() failed for stderr: " << strerror (errno) << std::endl;
114+ _exit (1 );
115+ }
99116
100117 close (pipeStdin[0 ]);
101118 close (pipeStdout[1 ]);
119+ close (pipeStderr[1 ]);
102120
103121 std::vector<char *> cargs;
104122 cargs.reserve (Args.size () + 2 );
@@ -115,19 +133,26 @@ void TPipe::TPipeLow::Fork() {
115133 // Parent process
116134 close (pipeStdin[0 ]);
117135 close (pipeStdout[1 ]);
136+ close (pipeStderr[1 ]);
118137
119138 ChildPid = pid;
120139 WriteFd = pipeStdin[1 ];
121140 ReadFd = pipeStdout[0 ];
141+ ErrFd = pipeStderr[0 ];
122142 SetNonBlocking (ReadFd);
123143 SetNonBlocking (WriteFd);
144+ SetNonBlocking (ErrFd);
124145 }
125146}
126147
127148TFuture<ssize_t > TPipe::ReadSome (void * buffer, size_t size) {
128149 co_return co_await ReadHandle->ReadSome (buffer, size);
129150}
130151
152+ TFuture<ssize_t > TPipe::ReadSomeErr (void * buffer, size_t size) {
153+ co_return co_await ErrHandle->ReadSome (buffer, size);
154+ }
155+
131156TFuture<ssize_t > TPipe::WriteSome (const void * buffer, size_t size) {
132157 co_return co_await WriteHandle->WriteSome (buffer, size);
133158}
0 commit comments