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
use std::{ convert::TryInto, io::{Error, Result}, process::Child, }; use nix::{ sys::signal::{kill, Signal}, unistd::Pid, }; /// Unix-specific extensions to process [`Child`]ren. pub trait UnixChildExt { /// Sends a signal to the child process. If the process has already exited, an [`InvalidInput`] /// error is returned. /// /// # Examples /// /// Basic usage: /// /// ```no_run /// use std::process::Command; /// use command_group::{UnixChildExt, Signal}; /// /// let mut command = Command::new("yes"); /// if let Ok(mut child) = command.spawn() { /// child.signal(Signal::SIGTERM).expect("command wasn't running"); /// } else { /// println!("yes command didn't start"); /// } /// ``` /// /// With a process group: /// /// ```no_run /// use std::process::Command; /// use command_group::{CommandGroup, UnixChildExt, Signal}; /// /// let mut command = Command::new("yes"); /// if let Ok(mut child) = command.group_spawn() { /// child.signal(Signal::SIGTERM).expect("command wasn't running"); /// } else { /// println!("yes command didn't start"); /// } /// ``` /// /// [`InvalidInput`]: std::io::ErrorKind::InvalidInput fn signal(&mut self, sig: Signal) -> Result<()>; } impl UnixChildExt for super::GroupChild { fn signal(&mut self, sig: Signal) -> Result<()> { self.imp.signal_imp(sig) } } impl UnixChildExt for Child { fn signal(&mut self, sig: Signal) -> Result<()> { let pid = Pid::from_raw(self.id().try_into().expect("Command PID > i32::MAX")); kill(pid, sig).map_err(Error::from) } }