8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
11
- // ignore-test
12
-
13
11
extern crate libc;
14
12
15
13
use std:: io:: process:: Command ;
@@ -18,51 +16,38 @@ use std::iter::IteratorExt;
18
16
use libc:: funcs:: posix88:: unistd;
19
17
20
18
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
24
22
// 2 0 [kthreadd]
25
- // 3 0 [ksoftirqd/0]
26
23
// ...
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>
30
29
// ...
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
35
32
// ...
36
33
37
34
#[ cfg( unix) ]
38
35
fn 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 ( ) } ;
50
37
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 ( ) ;
52
40
let ps_output = String :: from_utf8_lossy ( ps_cmd_output. output . as_slice ( ) ) ;
53
41
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) ;
62
49
}
63
- ) ;
64
-
65
- assert ! ( ! found, "Found at least one zombie child" ) ;
50
+ }
66
51
}
67
52
68
53
#[ cfg( windows) ]
@@ -71,10 +56,13 @@ fn find_zombies() { }
71
56
fn main ( ) {
72
57
let too_long = format ! ( "/NoSuchCommand{:0300}" , 0u8 ) ;
73
58
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
+ } ) ;
78
65
79
66
find_zombies ( ) ;
67
+ // then _failures goes out of scope
80
68
}
0 commit comments