//! Command execution module. //! use std::ffi::OsStr; use std::process::{Command,Child}; use std::io::{Result, Error, ErrorKind}; use libc::c_int; use libc::types::os::arch::posix88::pid_t; const WNOHANG: c_int = 0x00000001; extern { /// wait for a child process to stop or terminate. pub fn waitpid(pid: pid_t, stat_loc: *mut c_int, options: c_int) -> pid_t; } /// Extension to the Child struct that allows to check the status without block the /// current thread. pub trait ChildExt { fn wait_nohang(&mut self) -> Result; } impl ChildExt for Child { /// Checks if the calling child is a zombie and try to kill it, returning /// if it was killed or not. fn wait_nohang(&mut self) -> Result { let mut stat = 0i32; let pid = unsafe { waitpid(self.id() as i32, &mut stat, WNOHANG) }; if pid < 0 { Err(Error::new(ErrorKind::NotFound, format!("pid not found {}", pid))) } else { if pid > 0 { Ok(self.wait() .map(|x| { x.success() }).unwrap_or(false)) } else { Ok(false) } } } } /// Executes the given command. pub fn exec_cmd>(program: S, args: &[S]) -> Result { Command::new(program).args(args).spawn() }