File tree Expand file tree Collapse file tree 5 files changed +32
-14
lines changed Expand file tree Collapse file tree 5 files changed +32
-14
lines changed Original file line number Diff line number Diff line change @@ -1904,8 +1904,8 @@ impl FromInner<imp::ExitCode> for ExitCode {
19041904}
19051905
19061906impl Child {
1907- /// Forces the child process to exit. If the child has already exited, an [`InvalidInput`]
1908- /// error is returned.
1907+ /// Forces the child process to exit. If the child has already exited, `Ok(())`
1908+ /// is returned.
19091909 ///
19101910 /// The mapping to [`ErrorKind`]s is not part of the compatibility contract of the function.
19111911 ///
@@ -1920,7 +1920,7 @@ impl Child {
19201920 ///
19211921 /// let mut command = Command::new("yes");
19221922 /// if let Ok(mut child) = command.spawn() {
1923- /// child.kill().expect("command wasn 't running ");
1923+ /// child.kill().expect("command couldn 't be killed ");
19241924 /// } else {
19251925 /// println!("yes command didn't start");
19261926 /// }
Original file line number Diff line number Diff line change @@ -582,3 +582,18 @@ fn run_canonical_bat_script() {
582582 assert ! ( output. status. success( ) ) ;
583583 assert_eq ! ( String :: from_utf8_lossy( & output. stdout) . trim( ) , "Hello, fellow Rustaceans!" ) ;
584584}
585+
586+ #[ test]
587+ fn terminate_exited_process ( ) {
588+ let mut cmd = if cfg ! ( target_os = "android" ) {
589+ let mut p = shell_cmd ( ) ;
590+ p. args ( & [ "-c" , "true" ] ) ;
591+ p
592+ } else {
593+ known_command ( )
594+ } ;
595+ let mut p = cmd. stdout ( Stdio :: null ( ) ) . spawn ( ) . unwrap ( ) ;
596+ p. wait ( ) . unwrap ( ) ;
597+ assert ! ( p. kill( ) . is_ok( ) ) ;
598+ assert ! ( p. kill( ) . is_ok( ) ) ;
599+ }
Original file line number Diff line number Diff line change @@ -762,12 +762,9 @@ impl Process {
762762 pub fn kill ( & mut self ) -> io:: Result < ( ) > {
763763 // If we've already waited on this process then the pid can be recycled
764764 // and used for another process, and we probably shouldn't be killing
765- // random processes, so just return an error .
765+ // random processes, so return Ok because the process has exited already .
766766 if self . status . is_some ( ) {
767- Err ( io:: const_io_error!(
768- ErrorKind :: InvalidInput ,
769- "invalid argument: can't kill an exited process" ,
770- ) )
767+ Ok ( ( ) )
771768 } else {
772769 cvt ( unsafe { libc:: kill ( self . pid , libc:: SIGKILL ) } ) . map ( drop)
773770 }
Original file line number Diff line number Diff line change @@ -144,12 +144,9 @@ impl Process {
144144 pub fn kill ( & mut self ) -> io:: Result < ( ) > {
145145 // If we've already waited on this process then the pid can be recycled
146146 // and used for another process, and we probably shouldn't be killing
147- // random processes, so just return an error .
147+ // random processes, so return Ok because the process has exited already .
148148 if self . status . is_some ( ) {
149- Err ( io:: const_io_error!(
150- ErrorKind :: InvalidInput ,
151- "invalid argument: can't kill an exited process" ,
152- ) )
149+ Ok ( ( ) )
153150 } else {
154151 cvt ( unsafe { libc:: kill ( self . pid , libc:: SIGKILL ) } ) . map ( drop)
155152 }
Original file line number Diff line number Diff line change @@ -595,7 +595,16 @@ pub struct Process {
595595
596596impl Process {
597597 pub fn kill ( & mut self ) -> io:: Result < ( ) > {
598- cvt ( unsafe { c:: TerminateProcess ( self . handle . as_raw_handle ( ) , 1 ) } ) ?;
598+ let result = unsafe { c:: TerminateProcess ( self . handle . as_raw_handle ( ) , 1 ) } ;
599+ if result == c:: FALSE {
600+ let error = unsafe { c:: GetLastError ( ) } ;
601+ // TerminateProcess returns ERROR_ACCESS_DENIED if the process has already been
602+ // terminated (by us, or for any other reason). So check if the process was actually
603+ // terminated, and if so, do not return an error.
604+ if error != c:: ERROR_ACCESS_DENIED || self . try_wait ( ) . is_err ( ) {
605+ return Err ( crate :: io:: Error :: from_raw_os_error ( error as i32 ) ) ;
606+ }
607+ }
599608 Ok ( ( ) )
600609 }
601610
You can’t perform that action at this time.
0 commit comments