Skip to content

Commit b1086ce

Browse files
committed
wait-forked-but-failed-child
1 parent b987f40 commit b1086ce

File tree

1 file changed

+30
-17
lines changed

1 file changed

+30
-17
lines changed

tests/ui/process/process-spawn-failure.rs

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
//! Tests that repeatedly spawning a failing command does not create zombie processes.
2+
//! Spawns a deliberately invalid command multiple times, verifies each spawn fails,
3+
//! then uses `ps` (on Unix) to detect any leftover zombie (defunct) child processes.
4+
//! Checks Rust's process spawning cleans up resources properly.
5+
//! Skipped on platforms without `ps` utility.
6+
17
//@ run-pass
28
//@ needs-subprocess
39
//@ ignore-vxworks no 'ps'
@@ -36,35 +42,42 @@ fn find_zombies() {
3642
// the PPID column contains a "-" for the respective process.
3743
// Filter out any lines that have a "-" as the PPID as the PPID is
3844
// expected to be an integer.
39-
let filtered_ps: Vec<_> = ps_output
40-
.lines()
41-
.filter(|line| line.split_whitespace().nth(1) != Some("-"))
42-
.collect();
45+
let filtered_ps: Vec<_> =
46+
ps_output.lines().filter(|line| line.split_whitespace().nth(1) != Some("-")).collect();
4347

4448
for (line_no, line) in filtered_ps.into_iter().enumerate() {
45-
if 0 < line_no && 0 < line.len() &&
46-
my_pid == line.split(' ').filter(|w| 0 < w.len()).nth(1)
47-
.expect("1st column should be PPID")
48-
.parse().ok()
49-
.expect("PPID string into integer") &&
50-
line.contains("defunct") {
49+
if 0 < line_no
50+
&& 0 < line.len()
51+
&& my_pid
52+
== line
53+
.split(' ')
54+
.filter(|w| 0 < w.len())
55+
.nth(1)
56+
.expect("1st column should be PPID")
57+
.parse()
58+
.ok()
59+
.expect("PPID string into integer")
60+
&& line.contains("defunct")
61+
{
5162
panic!("Zombie child {}", line);
5263
}
5364
}
5465
}
5566

5667
#[cfg(windows)]
57-
fn find_zombies() { }
68+
fn find_zombies() {}
5869

5970
fn main() {
6071
let too_long = format!("/NoSuchCommand{:0300}", 0u8);
6172

62-
let _failures = (0..100).map(|_| {
63-
let mut cmd = Command::new(&too_long);
64-
let failed = cmd.spawn();
65-
assert!(failed.is_err(), "Make sure the command fails to spawn(): {:?}", cmd);
66-
failed
67-
}).collect::<Vec<_>>();
73+
let _failures = (0..100)
74+
.map(|_| {
75+
let mut cmd = Command::new(&too_long);
76+
let failed = cmd.spawn();
77+
assert!(failed.is_err(), "Make sure the command fails to spawn(): {:?}", cmd);
78+
failed
79+
})
80+
.collect::<Vec<_>>();
6881

6982
find_zombies();
7083
// then _failures goes out of scope

0 commit comments

Comments
 (0)