88// option. This file may not be copied, modified, or distributed
99// except according to those terms.
1010
11- // ignore-test
12-
1311extern crate libc;
1412
1513use std:: io:: process:: Command ;
@@ -18,51 +16,38 @@ use std::iter::IteratorExt;
1816use libc:: funcs:: posix88:: unistd;
1917
2018
21- // "ps -A -o pid,sid,command" with GNU ps should output something like this:
22- // PID SID COMMAND
23- // 1 1 /sbin/init
19+ // The output from "ps -A -o pid,ppid,args" should look like this:
20+ // PID PPID COMMAND
21+ // 1 0 /sbin/init
2422// 2 0 [kthreadd]
25- // 3 0 [ksoftirqd/0]
2623// ...
27- // 12562 9237 ./spawn-failure
28- // 12563 9237 [spawn-failure] <defunct>
29- // 12564 9237 [spawn-failure] <defunct>
24+ // 6076 9064 /bin/zsh
25+ // ...
26+ // 7164 6076 ./spawn-failure
27+ // 7165 7164 [spawn-failure] <defunct>
28+ // 7166 7164 [spawn-failure] <defunct>
3029// ...
31- // 12592 9237 [spawn-failure] <defunct>
32- // 12593 9237 ps -A -o pid,sid,command
33- // 12884 12884 /bin/zsh
34- // 12922 12922 /bin/zsh
30+ // 7197 7164 [spawn-failure] <defunct>
31+ // 7198 7164 ps -A -o pid,ppid,command
3532// ...
3633
3734#[ cfg( unix) ]
3835fn find_zombies ( ) {
39- // http://man.freebsd.org/ps(1)
40- // http://man7.org/linux/man-pages/man1/ps.1.html
41- #[ cfg( not( target_os = "macos" ) ) ]
42- const FIELDS : & ' static str = "pid,sid,command" ;
43-
44- // https://developer.apple.com/library/mac/documentation/Darwin/
45- // Reference/ManPages/man1/ps.1.html
46- #[ cfg( target_os = "macos" ) ]
47- const FIELDS : & ' static str = "pid,sess,command" ;
48-
49- let my_sid = unsafe { unistd:: getsid ( 0 ) } ;
36+ let my_pid = unsafe { unistd:: getpid ( ) } ;
5037
51- let ps_cmd_output = Command :: new ( "ps" ) . args ( & [ "-A" , "-o" , FIELDS ] ) . output ( ) . unwrap ( ) ;
38+ // http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ps.html
39+ let ps_cmd_output = Command :: new ( "ps" ) . args ( & [ "-A" , "-o" , "pid,ppid,args" ] ) . output ( ) . unwrap ( ) ;
5240 let ps_output = String :: from_utf8_lossy ( ps_cmd_output. output . as_slice ( ) ) ;
5341
54- let found = ps_output. split ( '\n' ) . enumerate ( ) . any ( |( line_no, line) |
55- 0 < line_no && 0 < line. len ( ) &&
56- my_sid == from_str ( line. split ( ' ' ) . filter ( |w| 0 < w. len ( ) ) . nth ( 1 )
57- . expect ( "1st column should be Session ID" )
58- ) . expect ( "Session ID string into integer" ) &&
59- line. contains ( "defunct" ) && {
60- println ! ( "Zombie child {}" , line) ;
61- true
42+ for ( line_no, line) in ps_output. split ( '\n' ) . enumerate ( ) {
43+ if 0 < line_no && 0 < line. len ( ) &&
44+ my_pid == from_str ( line. split ( ' ' ) . filter ( |w| 0 < w. len ( ) ) . nth ( 1 )
45+ . expect ( "1st column should be PPID" )
46+ ) . expect ( "PPID string into integer" ) &&
47+ line. contains ( "defunct" ) {
48+ panic ! ( "Zombie child {}" , line) ;
6249 }
63- ) ;
64-
65- assert ! ( ! found, "Found at least one zombie child" ) ;
50+ }
6651}
6752
6853#[ cfg( windows) ]
@@ -71,10 +56,13 @@ fn find_zombies() { }
7156fn main ( ) {
7257 let too_long = format ! ( "/NoSuchCommand{:0300}" , 0u8 ) ;
7358
74- for _ in range ( 0u32 , 100 ) {
75- let invalid = Command :: new ( too_long. as_slice ( ) ) . spawn ( ) ;
76- assert ! ( invalid. is_err( ) ) ;
77- }
59+ let _failures = Vec :: from_fn ( 100 , |_i| {
60+ let cmd = Command :: new ( too_long. as_slice ( ) ) ;
61+ let failed = cmd. spawn ( ) ;
62+ assert ! ( failed. is_err( ) , "Make sure the command fails to spawn(): {}" , cmd) ;
63+ failed
64+ } ) ;
7865
7966 find_zombies ( ) ;
67+ // then _failures goes out of scope
8068}
0 commit comments