1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
extern crate libc; #[cfg(target_os = "freebsd")] use std::os::unix::io::RawFd; #[derive(Debug)] pub struct ChildHandle { pub child_pid: libc::pid_t, #[cfg(target_os = "freebsd")] pub child_pd: RawFd, } impl ChildHandle { #[cfg(target_os = "freebsd")] pub fn signal(&self, sig: libc::c_int) -> bool { unsafe { libc::pdkill(self.child_pd, sig) == 0 } } #[cfg(not(target_os = "freebsd"))] pub fn signal(&self, sig: libc::c_int) -> bool { unsafe { libc::kill(self.child_pid, sig) == 0 } } } #[cfg(target_os = "freebsd")] impl Drop for ChildHandle { fn drop(&mut self) { unsafe { libc::close(self.child_pd) }; } } pub enum ForkResult { Parent(ChildHandle), Child, Fail, } #[cfg(target_os = "freebsd")] pub fn fork() -> ForkResult { let mut child_pd = -1; let child_pid = unsafe { libc::pdfork(&mut child_pd, 0) }; if child_pid < 0 { ForkResult::Fail } else if child_pid > 0 { ForkResult::Parent(ChildHandle { child_pid, child_pd, }) } else { ForkResult::Child } } #[cfg(not(target_os = "freebsd"))] pub fn fork() -> ForkResult { let child_pid = unsafe { libc::fork() }; if child_pid < 0 { ForkResult::Fail } else if child_pid > 0 { ForkResult::Parent(ChildHandle { child_pid, }) } else { ForkResult::Child } }