File tree Expand file tree Collapse file tree 2 files changed +26
-1
lines changed
Expand file tree Collapse file tree 2 files changed +26
-1
lines changed Original file line number Diff line number Diff line change @@ -850,8 +850,14 @@ impl Process {
850850 }
851851
852852 /// Is this process still alive?
853+ ///
854+ /// Processes in the Zombie or Dead state are not considered alive.
853855 pub fn is_alive ( & self ) -> bool {
854- rustix:: fs:: statat ( & self . fd , "stat" , AtFlags :: empty ( ) ) . is_ok ( )
856+ if let Ok ( stat) = self . stat ( ) {
857+ stat. state != 'Z' && stat. state != 'X'
858+ } else {
859+ false
860+ }
855861 }
856862
857863 /// What user owns this process?
Original file line number Diff line number Diff line change @@ -204,6 +204,25 @@ fn test_smaps() {
204204fn test_proc_alive ( ) {
205205 let myself = Process :: myself ( ) . unwrap ( ) ;
206206 assert ! ( myself. is_alive( ) ) ;
207+
208+ // zombies should not be considered alive
209+ let mut command = std:: process:: Command :: new ( "sleep" ) ;
210+ command
211+ . arg ( "0" )
212+ . stdout ( std:: process:: Stdio :: null ( ) )
213+ . stderr ( std:: process:: Stdio :: null ( ) ) ;
214+ let mut child = command. spawn ( ) . unwrap ( ) ;
215+ let child_pid = child. id ( ) as i32 ;
216+
217+ // sleep very briefly to allow the child to start and then exit
218+ std:: thread:: sleep ( std:: time:: Duration :: from_millis ( 20 ) ) ;
219+
220+ let child_proc = Process :: new ( child_pid) . unwrap ( ) ;
221+ assert ! ( !child_proc. is_alive( ) , "Child state is: {:?}" , child_proc. stat( ) ) ;
222+ assert ! ( child_proc. stat( ) . unwrap( ) . state( ) . unwrap( ) == ProcState :: Zombie ) ;
223+ child. wait ( ) . unwrap ( ) ;
224+ assert ! ( Process :: new( child_pid) . is_err( ) ) ;
225+ assert ! ( !child_proc. is_alive( ) , "Child state is: {:?}" , child_proc. stat( ) ) ;
207226}
208227
209228#[ test]
You can’t perform that action at this time.
0 commit comments