Skip to content

Wait for pid without polling using kevent on MacOS/BSD #1415

@Randomblock1

Description

@Randomblock1

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):

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.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions