Here's how I did it in my program (before realizing nix crate had event feature that let me not use unsafe):
use nix::libc;
let pid = 123;
unsafe {
let mut kev = libc::kevent {
ident: pid as usize,
filter: libc::EVFILT_PROC,
flags: libc::EV_ADD | libc::EV_ENABLE | libc::EV_ONESHOT | libc::EV_ERROR,
fflags: libc::NOTE_EXITSTATUS,
data: 0 as isize,
udata: 0 as *mut std::os::raw::c_void,
};
libc::kevent(libc::kqueue(), &kev, 1, &mut kev, 1, std::ptr::null());
if kev.flags & libc::EV_ERROR != 0 {
if kev.data == libc::ESRCH as isize {
println!("PID {} not found", pid);
} else {
eprintln!("kevent error waiting for PID {}", pid);
}
process::exit(1);
}
process::exit(kev.data as i32);
}
Probably not really needed since polling works fine but it'd be nice to have.
On MacOS (and BSD), you can wait for a process to finish using kqueue/kevent (https://man.freebsd.org/cgi/man.cgi?query=kevent&manpath=FreeBSD+9.0-RELEASE) instead of polling waitpid. An old Apple technical note mentions this, which is how I originally found this. You can also get the exit status from the completed event this way.
Here's how I did it in my program (before realizing nix crate had event feature that let me not use unsafe):
Probably not really needed since polling works fine but it'd be nice to have.