@@ -134,7 +134,7 @@ fn test_tls_set() {
134134}
135135
136136#[ test]
137- fn test_pipe ( ) {
137+ fn test_pipe ( ) -> CmdResult {
138138 assert ! ( run_cmd!( echo "xx" ) . is_ok( ) ) ;
139139 assert_eq ! ( run_fun!( echo "xx" ) . unwrap( ) , "xx" ) ;
140140 assert ! ( run_cmd!( echo xx | wc) . is_ok( ) ) ;
@@ -271,6 +271,64 @@ fn test_pipe() {
271271 }
272272
273273 assert ! ( ok) ;
274+
275+ // test that illustrates the bugs in wait_with_pipe()
276+ // FIXME: make set_pipefail() thread safe, then move this to a separate test function
277+ assert ! ( spawn_with_output!( false ) ?. wait_with_all( ) . 0 . is_err( ) ) ;
278+ assert ! ( spawn_with_output!( false ) ?. wait_with_output( ) . is_err( ) ) ;
279+ assert ! ( spawn_with_output!( false ) ?
280+ . wait_with_raw_output( & mut vec![ ] )
281+ . is_err( ) ) ;
282+
283+ // wait_with_pipe() can’t check the exit status of the last child
284+ assert ! ( spawn_with_output!( false ) ?
285+ . wait_with_pipe( & mut |_stdout| { } )
286+ . is_ok( ) ) ;
287+
288+ // wait_with_pipe() kills the last child when the provided function returns
289+ assert ! ( spawn_with_output!( sh -c "while :; do :; done" ) ?
290+ . wait_with_pipe( & mut |_stdout| { } )
291+ . is_ok( ) ) ;
292+
293+ // wait_with_pipe_thread() checks the exit status of the last child, even if pipefail is disabled
294+ set_pipefail ( false ) ;
295+ assert ! ( spawn_with_output!( true | false ) ?
296+ . wait_with_pipe_thread( |_stdout| { } )
297+ . is_err( ) ) ;
298+ assert ! ( spawn_with_output!( true | true ) ?
299+ . wait_with_pipe_thread( |_stdout| { } )
300+ . is_ok( ) ) ;
301+ assert ! ( spawn_with_output!( false ) ?
302+ . wait_with_pipe_thread( |_stdout| { } )
303+ . is_err( ) ) ;
304+ assert ! ( spawn_with_output!( true ) ?
305+ . wait_with_pipe_thread( |_stdout| { } )
306+ . is_ok( ) ) ;
307+ set_pipefail ( true ) ;
308+ // wait_with_pipe_thread() checks the exit status of the other children, unless pipefail is disabled
309+ set_pipefail ( false ) ;
310+ assert ! ( spawn_with_output!( false | true ) ?
311+ . wait_with_pipe_thread( |_stdout| { } )
312+ . is_ok( ) ) ;
313+ set_pipefail ( true ) ;
314+ assert ! ( spawn_with_output!( false | true ) ?
315+ . wait_with_pipe_thread( |_stdout| { } )
316+ . is_err( ) ) ;
317+ assert ! ( spawn_with_output!( true | true ) ?
318+ . wait_with_pipe_thread( |_stdout| { } )
319+ . is_ok( ) ) ;
320+ // wait_with_pipe_thread() handles `ignore`
321+ assert ! ( spawn_with_output!( ignore false | true ) ?
322+ . wait_with_pipe_thread( |_stdout| { } )
323+ . is_ok( ) ) ;
324+ assert ! ( spawn_with_output!( ignore true | false ) ?
325+ . wait_with_pipe_thread( |_stdout| { } )
326+ . is_ok( ) ) ;
327+ assert ! ( spawn_with_output!( ignore false ) ?
328+ . wait_with_pipe_thread( |_stdout| { } )
329+ . is_ok( ) ) ;
330+
331+ Ok ( ( ) )
274332}
275333
276334#[ test]
0 commit comments