fix(process): safely exit forked child after spawn
Co-Authored-By: Michael Murphy <michael@mmurphy.dev>
This commit is contained in:
parent
631c81b170
commit
5782cb927e
1 changed files with 16 additions and 7 deletions
|
|
@ -5,7 +5,7 @@
|
||||||
use smol::io::AsyncReadExt;
|
use smol::io::AsyncReadExt;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::os::fd::OwnedFd;
|
use std::os::fd::OwnedFd;
|
||||||
use std::process::{Command, Stdio, exit};
|
use std::process::{Command, Stdio};
|
||||||
#[cfg(feature = "tokio")]
|
#[cfg(feature = "tokio")]
|
||||||
use tokio::io::AsyncReadExt;
|
use tokio::io::AsyncReadExt;
|
||||||
|
|
||||||
|
|
@ -56,24 +56,33 @@ pub async fn spawn(mut command: Command) -> Option<u32> {
|
||||||
|
|
||||||
match unsafe { libc::fork() } {
|
match unsafe { libc::fork() } {
|
||||||
// Parent process
|
// Parent process
|
||||||
1.. => {
|
fork_pid @ 1..=i32::MAX => {
|
||||||
// Drop copy of write end, then read PID from pipe
|
// Drop copy of write end, then read PID from pipe
|
||||||
drop(write);
|
drop(write);
|
||||||
let pid = read_from_pipe(read).await;
|
let pid = read_from_pipe(read).await;
|
||||||
// wait to prevent zombie
|
_ = rustix::process::waitpid(
|
||||||
_ = rustix::process::wait(rustix::process::WaitOptions::empty());
|
rustix::process::Pid::from_raw(fork_pid),
|
||||||
|
rustix::process::WaitOptions::empty(),
|
||||||
|
);
|
||||||
pid
|
pid
|
||||||
}
|
}
|
||||||
|
|
||||||
// Child process
|
// Child process
|
||||||
0 => {
|
0 => {
|
||||||
let _res = rustix::process::setsid();
|
let _res = rustix::process::setsid();
|
||||||
if let Ok(child) = command.spawn() {
|
let exit_status = if let Ok(child) = command.spawn() {
|
||||||
// Write PID to pipe
|
// Write PID to pipe
|
||||||
let _ = rustix::io::write(write, &child.id().to_be_bytes());
|
let _ = rustix::io::write(write, &child.id().to_be_bytes());
|
||||||
}
|
0
|
||||||
|
} else {
|
||||||
|
1
|
||||||
|
};
|
||||||
|
|
||||||
exit(0)
|
// # Safety
|
||||||
|
// Required for child fork to exit without affecting the parent.
|
||||||
|
unsafe {
|
||||||
|
libc::_exit(exit_status);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
..=-1 => {
|
..=-1 => {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue