File tree 5 files changed +32
-14
lines changed
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 {
1904
1904
}
1905
1905
1906
1906
impl 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.
1909
1909
///
1910
1910
/// The mapping to [`ErrorKind`]s is not part of the compatibility contract of the function.
1911
1911
///
@@ -1920,7 +1920,7 @@ impl Child {
1920
1920
///
1921
1921
/// let mut command = Command::new("yes");
1922
1922
/// if let Ok(mut child) = command.spawn() {
1923
- /// child.kill().expect("command wasn 't running ");
1923
+ /// child.kill().expect("command couldn 't be killed ");
1924
1924
/// } else {
1925
1925
/// println!("yes command didn't start");
1926
1926
/// }
Original file line number Diff line number Diff line change @@ -582,3 +582,18 @@ fn run_canonical_bat_script() {
582
582
assert ! ( output. status. success( ) ) ;
583
583
assert_eq ! ( String :: from_utf8_lossy( & output. stdout) . trim( ) , "Hello, fellow Rustaceans!" ) ;
584
584
}
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 {
762
762
pub fn kill ( & mut self ) -> io:: Result < ( ) > {
763
763
// If we've already waited on this process then the pid can be recycled
764
764
// 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 .
766
766
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 ( ( ) )
771
768
} else {
772
769
cvt ( unsafe { libc:: kill ( self . pid , libc:: SIGKILL ) } ) . map ( drop)
773
770
}
Original file line number Diff line number Diff line change @@ -144,12 +144,9 @@ impl Process {
144
144
pub fn kill ( & mut self ) -> io:: Result < ( ) > {
145
145
// If we've already waited on this process then the pid can be recycled
146
146
// 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 .
148
148
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 ( ( ) )
153
150
} else {
154
151
cvt ( unsafe { libc:: kill ( self . pid , libc:: SIGKILL ) } ) . map ( drop)
155
152
}
Original file line number Diff line number Diff line change @@ -595,7 +595,16 @@ pub struct Process {
595
595
596
596
impl Process {
597
597
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
+ }
599
608
Ok ( ( ) )
600
609
}
601
610
You can’t perform that action at this time.
0 commit comments