@@ -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( ) ) ;
@@ -158,6 +158,64 @@ fn test_pipe() {
158158 set_pipefail ( false ) ;
159159 assert ! ( run_fun!( false | true ) . is_ok( ) ) ;
160160 set_pipefail ( true ) ;
161+
162+ // test that illustrates the bugs in wait_with_pipe()
163+ // FIXME: make set_pipefail() thread safe, then move this to a separate test function
164+ assert ! ( spawn_with_output!( false ) ?. wait_with_all( ) . 0 . is_err( ) ) ;
165+ assert ! ( spawn_with_output!( false ) ?. wait_with_output( ) . is_err( ) ) ;
166+ assert ! ( spawn_with_output!( false ) ?
167+ . wait_with_raw_output( & mut vec![ ] )
168+ . is_err( ) ) ;
169+
170+ // wait_with_pipe() can’t check the exit status of the last child
171+ assert ! ( spawn_with_output!( false ) ?
172+ . wait_with_pipe( & mut |_stdout| { } )
173+ . is_ok( ) ) ;
174+
175+ // wait_with_pipe() kills the last child when the provided function returns
176+ assert ! ( spawn_with_output!( sh -c "while :; do :; done" ) ?
177+ . wait_with_pipe( & mut |_stdout| { } )
178+ . is_ok( ) ) ;
179+
180+ // wait_with_pipe_thread() checks the exit status of the last child, even if pipefail is disabled
181+ set_pipefail ( false ) ;
182+ assert ! ( spawn_with_output!( true | false ) ?
183+ . wait_with_pipe_thread( |_stdout| { } )
184+ . is_err( ) ) ;
185+ assert ! ( spawn_with_output!( true | true ) ?
186+ . wait_with_pipe_thread( |_stdout| { } )
187+ . is_ok( ) ) ;
188+ assert ! ( spawn_with_output!( false ) ?
189+ . wait_with_pipe_thread( |_stdout| { } )
190+ . is_err( ) ) ;
191+ assert ! ( spawn_with_output!( true ) ?
192+ . wait_with_pipe_thread( |_stdout| { } )
193+ . is_ok( ) ) ;
194+ set_pipefail ( true ) ;
195+ // wait_with_pipe_thread() checks the exit status of the other children, unless pipefail is disabled
196+ set_pipefail ( false ) ;
197+ assert ! ( spawn_with_output!( false | true ) ?
198+ . wait_with_pipe_thread( |_stdout| { } )
199+ . is_ok( ) ) ;
200+ set_pipefail ( true ) ;
201+ assert ! ( spawn_with_output!( false | true ) ?
202+ . wait_with_pipe_thread( |_stdout| { } )
203+ . is_err( ) ) ;
204+ assert ! ( spawn_with_output!( true | true ) ?
205+ . wait_with_pipe_thread( |_stdout| { } )
206+ . is_ok( ) ) ;
207+ // wait_with_pipe_thread() handles `ignore`
208+ assert ! ( spawn_with_output!( ignore false | true ) ?
209+ . wait_with_pipe_thread( |_stdout| { } )
210+ . is_ok( ) ) ;
211+ assert ! ( spawn_with_output!( ignore true | false ) ?
212+ . wait_with_pipe_thread( |_stdout| { } )
213+ . is_ok( ) ) ;
214+ assert ! ( spawn_with_output!( ignore false ) ?
215+ . wait_with_pipe_thread( |_stdout| { } )
216+ . is_ok( ) ) ;
217+
218+ Ok ( ( ) )
161219}
162220
163221#[ test]
0 commit comments