When I want to wait for a child process to finish, I make a Child::wait()
call:
let exit_status = Command::new("sudo")
.args(["umount", mountpoint])
.spawn()
.expect("Failed to spawn umount command")
.wait()
.expect("Failure while waiting for umount command");
This method returns a Result<ExitStatus>
. If the program finished with an error, it will return to me an Ok(ExitStatus)
that indicates a non-zero exit code. So I wonder why is this method failable... In which context does the waiting fail but the child process itself does not?
The documentation doesn't mention the reason, but the piece of code provides a suggestion:
// Code from the docs example.
use std::process::Command;
let mut command = Command::new("ls");
if let Ok(mut child) = command.spawn() {
child.wait().expect("command wasn't running");
println!("Child has finished its execution!");
} else {
println!("ls command didn't start");
}
"Command wasn't running"? But the spawning went alright. Does anybody have a clue?
On Linux this translates to the wait
syscall, which can signal errors. Therefore, the Rust API must be fallible, otherwise errors at the syscall level could not be reported.
As an example of how this could fail, if you have manually set the action for SIGCHLD
to SIG_IGN
, then child processes are automatically reaped by the kernel. A wait
syscall on a child that has terminated will then result in an ECHILD
error.