fn run_forked()

in reverie-process/src/exit_status.rs [159:207]


    fn run_forked<F>(f: F) -> nix::Result<ExitStatus>
    where
        F: FnOnce() -> nix::Result<()>,
    {
        match unsafe { fork() }? {
            ForkResult::Parent { child, .. } => {
                // Simply wait for the child to exit.
                match waitpid(child, None)? {
                    WaitStatus::Exited(_, code) => Ok(ExitStatus::Exited(code)),
                    WaitStatus::Signaled(_, sig, coredump) => {
                        Ok(ExitStatus::Signaled(sig, coredump))
                    }
                    wait_status => unreachable!("Got unexpected wait status: {:?}", wait_status),
                }
            }
            ForkResult::Child => {
                // Suppress core dumps for testing purposes.
                let limit = libc::rlimit {
                    rlim_cur: 0,
                    rlim_max: 0,
                };
                unsafe {
                    // restore some sighandlers to default
                    for &sig in &[libc::SIGALRM, libc::SIGINT, libc::SIGVTALRM] {
                        libc::signal(sig, libc::SIG_DFL);
                    }
                    // disable coredump
                    libc::setrlimit(libc::RLIMIT_CORE, &limit)
                };

                // Run the child.
                let code = match f() {
                    Ok(()) => 0,
                    Err(err) => {
                        eprintln!("{}", err);
                        1
                    }
                };

                // The closure should have called `exit` by this point, but just
                // in case it didn't, call it ourselves.
                //
                // Note: We also can't use the normal exit function here because we
                // don't want to call atexit handlers since `execve` was never
                // called.
                unsafe { ::libc::_exit(code) };
            }
        }
    }