1+ use std:: sync:: mpsc:: Sender ;
12use std:: {
23 fmt:: { self } ,
34 io:: { Read , Write } ,
@@ -156,6 +157,36 @@ impl Command {
156157 // }
157158 // }
158159
160+ fn spawn_pipe_thread < R , W > (
161+ mut reader : R ,
162+ sink : W ,
163+ tx : Sender < Vec < u8 > > ,
164+ ) -> thread:: JoinHandle < ( ) >
165+ where
166+ R : Read + Send + ' static ,
167+ W : Write + Send + ' static ,
168+ {
169+ thread:: spawn ( move || {
170+ let mut output = Vec :: new ( ) ;
171+ let mut buf = [ 0u8 ; 8192 ] ;
172+ let mut sink = sink;
173+
174+ loop {
175+ let n = match reader. read ( & mut buf) {
176+ Ok ( 0 ) => break ,
177+ Ok ( n) => n,
178+ Err ( _) => break ,
179+ } ;
180+
181+ output. extend_from_slice ( & buf[ ..n] ) ;
182+ let _ = sink. write_all ( & buf[ ..n] ) ;
183+ }
184+
185+ let _ = sink. flush ( ) ;
186+ let _ = tx. send ( output) ;
187+ } )
188+ }
189+
159190 /// Execute the command and capture both stdout and stderr while simultaneously printing them live if live is true
160191 pub fn try_call ( & self ) -> CommandResults {
161192 println ! ( "{self:#}" ) ;
@@ -177,61 +208,14 @@ impl Command {
177208 let stdout = child. stdout . take ( ) . expect ( "Failed to capture stdout" ) ;
178209 let stderr = child. stderr . take ( ) . expect ( "Failed to capture stderr" ) ;
179210
180- // Create channels to collect output
181211 let ( stdout_tx, stdout_rx) = std:: sync:: mpsc:: channel ( ) ;
182212 let ( stderr_tx, stderr_rx) = std:: sync:: mpsc:: channel ( ) ;
183213
184- fn ssd ( ) { }
185- // Spawn thread to read and print stdout
186- let stdout_thread = thread:: spawn ( move || {
187- let mut reader = stdout;
188- let mut output = Vec :: new ( ) ;
189- let mut buf = [ 0u8 ; 8192 ] ;
190-
191- let mut out = std:: io:: stdout ( ) . lock ( ) ;
192-
193- loop {
194- let n = match reader. read ( & mut buf) {
195- Ok ( 0 ) => break ,
196- Ok ( n) => n,
197- Err ( _) => break ,
198- } ;
199-
200- output. extend_from_slice ( & buf[ ..n] ) ;
201- let _ = out. write_all ( & buf[ ..n] ) ; // <-- bytes, not chars
202- let _ = out. flush ( ) ;
203- }
204-
205- let _ = stdout_tx. send ( output) ;
206- } ) ;
207-
208- // Spawn thread to read and print stderr
209- let stderr_thread = thread:: spawn ( move || {
210- let mut reader = stderr;
211- let mut output = Vec :: new ( ) ;
212- let mut buf = [ 0u8 ; 8192 ] ;
213-
214- let mut err = std:: io:: stderr ( ) . lock ( ) ;
215-
216- loop {
217- let n = match reader. read ( & mut buf) {
218- Ok ( 0 ) => break ,
219- Ok ( n) => n,
220- Err ( _) => break ,
221- } ;
222-
223- output. extend_from_slice ( & buf[ ..n] ) ;
224- let _ = err. write_all ( & buf[ ..n] ) ;
225- let _ = err. flush ( ) ;
226- }
227-
228- let _ = stderr_tx. send ( output) ;
229- } ) ;
230-
231- // Wait for the child process to complete
214+ let stdout_thread = Self :: spawn_pipe_thread ( stdout, std:: io:: stdout ( ) , stdout_tx) ;
215+ let stderr_thread = Self :: spawn_pipe_thread ( stderr, std:: io:: stderr ( ) , stderr_tx) ;
216+
232217 let status = child. wait ( ) . expect ( "Failed to wait on child process" ) ;
233218
234- // Wait for threads to finish and collect output
235219 stdout_thread. join ( ) . expect ( "Failed to join stdout thread" ) ;
236220 stderr_thread. join ( ) . expect ( "Failed to join stderr thread" ) ;
237221
0 commit comments