mirror of
https://github.com/rust-lang/rust.git
synced 2026-05-23 13:27:11 +03:00
3c8bfd144b
If an early return is found under the HIR local declaration node but before the child process is created, it should not trigger the lint because the child process has not yet been created.
211 lines
4.8 KiB
Rust
211 lines
4.8 KiB
Rust
#![warn(clippy::zombie_processes)]
|
|
#![allow(clippy::if_same_then_else, clippy::ifs_same_cond, clippy::needless_return)]
|
|
|
|
use std::process::{Child, Command, ExitStatus};
|
|
|
|
fn main() {
|
|
{
|
|
// Check that #[expect] works
|
|
#[expect(clippy::zombie_processes)]
|
|
let mut x = Command::new("").spawn().unwrap();
|
|
}
|
|
|
|
{
|
|
let mut x = Command::new("").spawn().unwrap();
|
|
//~^ zombie_processes
|
|
|
|
x.kill();
|
|
x.id();
|
|
}
|
|
{
|
|
let mut x = Command::new("").spawn().unwrap();
|
|
x.wait().unwrap(); // OK
|
|
}
|
|
{
|
|
let x = Command::new("").spawn().unwrap();
|
|
x.wait_with_output().unwrap(); // OK
|
|
}
|
|
{
|
|
let mut x = Command::new("").spawn().unwrap();
|
|
x.try_wait().unwrap(); // OK
|
|
}
|
|
{
|
|
let mut x = Command::new("").spawn().unwrap();
|
|
let mut r = &mut x;
|
|
r.wait().unwrap(); // OK, not calling `.wait()` directly on `x` but through `r` -> `x`
|
|
}
|
|
{
|
|
let mut x = Command::new("").spawn().unwrap();
|
|
process_child(x); // OK, other function might call `.wait()` so assume it does
|
|
}
|
|
{
|
|
let mut x = Command::new("").spawn().unwrap();
|
|
//~^ zombie_processes
|
|
|
|
let v = &x;
|
|
// (allow shared refs is fine because one cannot call `.wait()` through that)
|
|
}
|
|
|
|
// https://github.com/rust-lang/rust-clippy/pull/11476#issuecomment-1718456033
|
|
// Unconditionally exiting the process in various ways (should not lint)
|
|
{
|
|
let mut x = Command::new("").spawn().unwrap();
|
|
std::process::exit(0);
|
|
}
|
|
{
|
|
let mut x = Command::new("").spawn().unwrap();
|
|
std::process::abort(); // same as above, but abort instead of exit
|
|
}
|
|
{
|
|
let mut x = Command::new("").spawn().unwrap();
|
|
if true { /* nothing */ }
|
|
std::process::abort(); // still unconditionally exits
|
|
}
|
|
|
|
// Conditionally exiting
|
|
// It should assume that it might not exit and still lint
|
|
{
|
|
let mut x = Command::new("").spawn().unwrap();
|
|
//~^ zombie_processes
|
|
|
|
if true {
|
|
std::process::exit(0);
|
|
}
|
|
}
|
|
{
|
|
let mut x = Command::new("").spawn().unwrap();
|
|
//~^ zombie_processes
|
|
|
|
if true {
|
|
while false {}
|
|
// Calling `exit()` after leaving a while loop should still be linted.
|
|
std::process::exit(0);
|
|
}
|
|
}
|
|
|
|
{
|
|
let mut x = { Command::new("").spawn().unwrap() };
|
|
x.wait().unwrap();
|
|
}
|
|
|
|
{
|
|
struct S {
|
|
c: Child,
|
|
}
|
|
|
|
let mut s = S {
|
|
c: Command::new("").spawn().unwrap(),
|
|
};
|
|
s.c.wait().unwrap();
|
|
}
|
|
|
|
{
|
|
let mut x = Command::new("").spawn().unwrap();
|
|
//~^ zombie_processes
|
|
|
|
if true {
|
|
return;
|
|
}
|
|
x.wait().unwrap();
|
|
}
|
|
|
|
{
|
|
let mut x = Command::new("").spawn().unwrap();
|
|
//~^ zombie_processes
|
|
|
|
if true {
|
|
x.wait().unwrap();
|
|
}
|
|
}
|
|
|
|
{
|
|
let mut x = Command::new("").spawn().unwrap();
|
|
//~^ zombie_processes
|
|
|
|
if true {
|
|
x.wait().unwrap();
|
|
} else {
|
|
// this else block exists to test the other help message
|
|
}
|
|
}
|
|
|
|
{
|
|
let mut x = Command::new("").spawn().unwrap();
|
|
//~^ zombie_processes
|
|
|
|
if true {
|
|
// this else block exists to test the other help message
|
|
} else {
|
|
x.wait().unwrap();
|
|
}
|
|
}
|
|
|
|
{
|
|
let mut x = Command::new("").spawn().unwrap();
|
|
if true {
|
|
x.wait().unwrap();
|
|
} else if true {
|
|
x.wait().unwrap();
|
|
} else {
|
|
x.wait().unwrap();
|
|
}
|
|
}
|
|
|
|
{
|
|
let mut x = Command::new("").spawn().unwrap();
|
|
if true {
|
|
x.wait().unwrap();
|
|
return;
|
|
}
|
|
x.wait().unwrap();
|
|
}
|
|
|
|
{
|
|
let mut x = Command::new("").spawn().unwrap();
|
|
std::thread::spawn(move || {
|
|
x.wait().unwrap();
|
|
});
|
|
}
|
|
}
|
|
|
|
fn process_child(c: Child) {
|
|
todo!()
|
|
}
|
|
|
|
fn return_wait() -> ExitStatus {
|
|
let mut x = Command::new("").spawn().unwrap();
|
|
return x.wait().unwrap();
|
|
}
|
|
|
|
mod issue14677 {
|
|
use std::io;
|
|
use std::process::Command;
|
|
|
|
fn do_something<F: Fn() -> Result<(), ()>>(f: F) {
|
|
todo!()
|
|
}
|
|
|
|
fn foo() {
|
|
let mut child = Command::new("true").spawn().unwrap();
|
|
let some_condition = true;
|
|
do_something(|| {
|
|
if some_condition {
|
|
return Err(());
|
|
}
|
|
Ok(())
|
|
});
|
|
child.kill().unwrap();
|
|
child.wait().unwrap();
|
|
}
|
|
}
|
|
|
|
fn issue14911() -> std::io::Result<String> {
|
|
let (mut recv, send) = std::io::pipe()?;
|
|
let mut command = Command::new("ls")
|
|
.stdout(send.try_clone()?)
|
|
.spawn()
|
|
.expect("Could not spawn new process...");
|
|
command.wait()?;
|
|
Ok("".into())
|
|
}
|