Refactor Runner a bit; add Drop impl for eventual use

This commit is contained in:
Matt Green 2016-10-22 16:54:16 -04:00
parent a408975bdc
commit 83b91e51d0

View File

@ -26,22 +26,30 @@ impl Runner {
} }
#[cfg(target_family = "windows")] #[cfg(target_family = "windows")]
fn kill(child: &mut Child) { fn kill(&self) {
if let Some(ref child) = self.process {
debug!("Killing child process (pid: {})", child.id());
let _ = child.kill(); let _ = child.kill();
} }
}
#[cfg(target_family = "unix")] #[cfg(target_family = "unix")]
fn kill(child: &mut Child) { fn kill(&self) {
use libc; use libc;
extern { extern {
fn killpg(pgrp: libc::pid_t, sig: libc::c_int) -> libc::c_int; fn killpg(pgrp: libc::pid_t, sig: libc::c_int) -> libc::c_int;
} }
if let Some(ref child) = self.process {
debug!("Killing child process (pid: {})", child.id());
unsafe { unsafe {
killpg(child.id() as i32, libc::SIGTERM); killpg(child.id() as i32, libc::SIGTERM);
} }
} }
}
#[cfg(target_family = "windows")] #[cfg(target_family = "windows")]
fn invoke(&self, cmd: &str, updated_paths: Vec<&str>) -> Option<Child> { fn invoke(&self, cmd: &str, updated_paths: Vec<&str>) -> Option<Child> {
@ -52,6 +60,8 @@ impl Runner {
command.env("WATCHEXEC_UPDATED_PATH", updated_paths[0]); command.env("WATCHEXEC_UPDATED_PATH", updated_paths[0]);
} }
debug!("Executing: {}", cmd);
command.spawn().ok() command.spawn().ok()
} }
@ -67,6 +77,8 @@ impl Runner {
command.env("WATCHEXEC_UPDATED_PATH", updated_paths[0]); command.env("WATCHEXEC_UPDATED_PATH", updated_paths[0]);
} }
debug!("Executing: {}", cmd);
command command
.before_exec(|| unsafe { libc::setpgid(0, 0); Ok(()) }) .before_exec(|| unsafe { libc::setpgid(0, 0); Ok(()) })
.spawn() .spawn()
@ -74,39 +86,43 @@ impl Runner {
} }
pub fn run_command(&mut self, cmd: &str, updated_paths: Vec<&str>) { pub fn run_command(&mut self, cmd: &str, updated_paths: Vec<&str>) {
if let Some(ref mut child) = self.process {
if self.restart { if self.restart {
debug!("Killing child process (pid: {})", child.id()); self.kill();
Runner::kill(child);
} }
debug!("Waiting for child process (pid: {})", child.id()); self.wait();
Runner::wait(child);
}
if self.cls { if self.cls {
self.clear(); self.clear();
} }
debug!("Executing: {}", cmd);
self.process = self.invoke(cmd, updated_paths); self.process = self.invoke(cmd, updated_paths);
} }
#[cfg(target_family = "windows")] #[cfg(target_family = "windows")]
fn wait(child: &mut Child) { fn wait(&self) {
if let Some(ref child) = self.process {
debug!("Waiting for child process (pid: {})", child.id());
let _ = child.wait(); let _ = child.wait();
} }
}
#[cfg(target_family = "unix")] #[cfg(target_family = "unix")]
fn wait(child: &mut Child) { fn wait(&self) {
use libc; use nix::sys::wait::{waitpid};
if let Some(ref child) = self.process {
debug!("Waiting for child process (pid: {})", child.id());
unsafe {
let pid = child.id() as i32; let pid = child.id() as i32;
let status: Box<i32> = Box::new(0); let _ = waitpid(-pid, None);
libc::waitpid(-pid, Box::into_raw(status), 0);
} }
} }
}
impl Drop for Runner {
fn drop(&mut self) {
self.kill();
self.wait();
}
} }