Add -k option to send SIGKILL instead of SIGTERM; closes #31
This commit is contained in:
parent
787c31040c
commit
9c65e816da
2
Makefile
2
Makefile
|
@ -1,6 +1,6 @@
|
|||
VER=$(shell grep version Cargo.toml | head -n1 | grep -Eow '".+"' | sed 's/"//g')
|
||||
|
||||
.PHONY: doc
|
||||
.PHONY: doc test
|
||||
|
||||
debug: src/* Cargo.toml
|
||||
@cargo build
|
||||
|
|
|
@ -54,6 +54,10 @@ Call/restart `python server.py` when any Python file in the current directory (a
|
|||
|
||||
$ watchexec -e py -r python server.py
|
||||
|
||||
Call/restart `my_server` when any file in the current directory (and all subdirectories) changes, sending `SIGKILL` to stop the child process:
|
||||
|
||||
$ watchexec -r -k my_server
|
||||
|
||||
Run `make` when any file changes, using the `.gitignore` file in the current directory to filter:
|
||||
|
||||
$ watchexec make
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "WATCHEXEC" "1" "November 2016" "" ""
|
||||
.TH "WATCHEXEC" "1" "December 2016" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBwatchexec\fR \- execute commands when watched files change
|
||||
|
@ -30,12 +30,16 @@ Comma\-separated list of file extensions to filter by\. Leading dots are allowed
|
|||
Ignores modifications from paths that do not match \fIpattern\fR\. This option can be specified multiple times, where a match on any given pattern causes the path to trigger \fIcommand\fR\.
|
||||
.
|
||||
.TP
|
||||
\fB\-k\fR, \fB\-\-kill\fR
|
||||
Send \fBSIGKILL\fR to the child process group instead of \fBSIGTERM\fR\.
|
||||
.
|
||||
.TP
|
||||
\fB\-i\fR, \fB\-\-ignore\fR \fIpattern\fR
|
||||
Ignores modifications from paths that match \fIpattern\fR\. This option can be specified multiple times, and a match on any pattern causes the path to be ignored\.
|
||||
.
|
||||
.TP
|
||||
\fB\-r\fR, \fB\-\-restart\fR
|
||||
Sends \fBSIGTERM\fR to the child process if it is still running when subsequent file modifications are detected, then waits for the child to exit\.
|
||||
Terminates the child process group if it is still running when subsequent file modifications are detected\. By default, sends \fBSIGTERM\fR; use \fB\-\-kill\fR to send \fBSIGKILL\fR\.
|
||||
.
|
||||
.TP
|
||||
\fB\-c\fR, \fB\-\-clear\fR
|
||||
|
|
|
@ -88,8 +88,9 @@
|
|||
<dt class="flush"><var>cmd</var></dt><dd><p>Command to run when watched files are modified, and at startup, unless <code>--postpone</code> is specified. All <var>argument</var>s are passed to <var>cmd</var>.</p></dd>
|
||||
<dt><code>-e</code>, <code>--exts</code> <var>extensions</var></dt><dd><p>Comma-separated list of file extensions to filter by. Leading dots are allowed (.rs) are allowed. (This is a shorthand for <code>-f</code>).</p></dd>
|
||||
<dt><code>-f</code>, <code>--filter</code> <var>pattern</var></dt><dd><p>Ignores modifications from paths that do not match <var>pattern</var>. This option can be specified multiple times, where a match on any given pattern causes the path to trigger <em>command</em>.</p></dd>
|
||||
<dt><code>-k</code>, <code>--kill</code></dt><dd><p>Send <code>SIGKILL</code> to the child process group instead of <code>SIGTERM</code>.</p></dd>
|
||||
<dt><code>-i</code>, <code>--ignore</code> <em>pattern</em></dt><dd><p>Ignores modifications from paths that match <var>pattern</var>. This option can be specified multiple times, and a match on any pattern causes the path to be ignored.</p></dd>
|
||||
<dt><code>-r</code>, <code>--restart</code></dt><dd><p>Sends <code>SIGTERM</code> to the child process if it is still running when subsequent file modifications are detected, then waits for the child to exit.</p></dd>
|
||||
<dt><code>-r</code>, <code>--restart</code></dt><dd><p>Terminates the child process group if it is still running when subsequent file modifications are detected. By default, sends <code>SIGTERM</code>; use <code>--kill</code> to send <code>SIGKILL</code>.</p></dd>
|
||||
<dt><code>-c</code>, <code>--clear</code></dt><dd><p>Clears the screen before executing <var>command</var>.</p></dd>
|
||||
<dt><code>-p</code>, <code>--postpone</code></dt><dd><p>Postpone execution of <var>command</var> until the first file modification is detected.</p></dd>
|
||||
<dt><code>-d</code>, <code>--debug</code></dt><dd><p>Prints diagnostic messages to STDERR</p></dd>
|
||||
|
@ -127,7 +128,7 @@
|
|||
|
||||
<ol class='man-decor man-foot man foot'>
|
||||
<li class='tl'></li>
|
||||
<li class='tc'>November 2016</li>
|
||||
<li class='tc'>December 2016</li>
|
||||
<li class='tr'>watchexec(1)</li>
|
||||
</ol>
|
||||
|
||||
|
|
|
@ -22,11 +22,14 @@ Comma-separated list of file extensions to filter by. Leading dots are allowed (
|
|||
* `-f`, `--filter` <pattern>:
|
||||
Ignores modifications from paths that do not match <pattern>. This option can be specified multiple times, where a match on any given pattern causes the path to trigger *command*.
|
||||
|
||||
* `-k`, `--kill`:
|
||||
Send `SIGKILL` to the child process group instead of `SIGTERM`.
|
||||
|
||||
* `-i`, `--ignore` *pattern*:
|
||||
Ignores modifications from paths that match <pattern>. This option can be specified multiple times, and a match on any pattern causes the path to be ignored.
|
||||
|
||||
* `-r`, `--restart`:
|
||||
Sends `SIGTERM` to the child process if it is still running when subsequent file modifications are detected, then waits for the child to exit.
|
||||
Terminates the child process group if it is still running when subsequent file modifications are detected. By default, sends `SIGTERM`; use `--kill` to send `SIGKILL`.
|
||||
|
||||
* `-c`, `--clear`:
|
||||
Clears the screen before executing <command>.
|
||||
|
|
|
@ -9,6 +9,7 @@ pub struct Args {
|
|||
pub filters: Vec<String>,
|
||||
pub ignores: Vec<String>,
|
||||
pub clear_screen: bool,
|
||||
pub kill: bool,
|
||||
pub restart: bool,
|
||||
pub debug: bool,
|
||||
pub run_initially: bool,
|
||||
|
@ -81,6 +82,9 @@ pub fn get_args() -> Args {
|
|||
.help("Forces polling mode")
|
||||
.long("force-poll")
|
||||
.value_name("interval"))
|
||||
.arg(Arg::with_name("kill")
|
||||
.help("Send SIGKILL to child processes")
|
||||
.long("kill"))
|
||||
.get_matches();
|
||||
|
||||
let cmd = values_t!(args.values_of("command"), String).unwrap().join(" ");
|
||||
|
@ -115,6 +119,7 @@ pub fn get_args() -> Args {
|
|||
filters: filters,
|
||||
ignores: ignores,
|
||||
clear_screen: args.is_present("clear"),
|
||||
kill: args.is_present("kill"),
|
||||
restart: args.is_present("restart"),
|
||||
debug: args.is_present("debug"),
|
||||
run_initially: !args.is_present("postpone"),
|
||||
|
|
11
src/main.rs
11
src/main.rs
|
@ -79,8 +79,10 @@ fn init_logger(debug: bool) {
|
|||
}
|
||||
|
||||
fn main() {
|
||||
let args = cli::get_args();
|
||||
let child_process: Arc<RwLock<Option<Process>>> = Arc::new(RwLock::new(None));
|
||||
let weak_child = Arc::downgrade(&child_process);
|
||||
let kill = args.kill;
|
||||
|
||||
signal::install_handler(move |sig: Signal| {
|
||||
if let Some(lock) = weak_child.upgrade() {
|
||||
|
@ -88,7 +90,12 @@ fn main() {
|
|||
if let Some(ref child) = *strong {
|
||||
match sig {
|
||||
Signal::Terminate => {
|
||||
child.kill();
|
||||
if kill {
|
||||
child.kill();
|
||||
} else {
|
||||
child.terminate();
|
||||
}
|
||||
|
||||
child.wait();
|
||||
},
|
||||
Signal::Stop => {
|
||||
|
@ -102,8 +109,6 @@ fn main() {
|
|||
}
|
||||
});
|
||||
|
||||
let args = cli::get_args();
|
||||
|
||||
init_logger(args.debug);
|
||||
|
||||
let cwd = env::current_dir()
|
||||
|
|
|
@ -8,8 +8,7 @@ pub use self::imp::Process;
|
|||
|
||||
#[cfg(target_family = "unix")]
|
||||
mod imp {
|
||||
use libc::c_int;
|
||||
use libc::pid_t;
|
||||
use libc::*;
|
||||
use std::io::Result;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
|
@ -20,7 +19,6 @@ mod imp {
|
|||
|
||||
impl Process {
|
||||
pub fn new(cmd: &str, updated_paths: Vec<PathBuf>) -> Result<Process> {
|
||||
use libc::exit;
|
||||
use nix::unistd::*;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
|
@ -80,27 +78,19 @@ mod imp {
|
|||
}
|
||||
|
||||
pub fn kill(&self) {
|
||||
use libc::SIGTERM;
|
||||
|
||||
self.signal(SIGTERM);
|
||||
self.signal(SIGKILL);
|
||||
}
|
||||
|
||||
pub fn pause(&self) {
|
||||
use libc::SIGTSTP;
|
||||
|
||||
self.signal(SIGTSTP);
|
||||
}
|
||||
|
||||
|
||||
pub fn resume(&self) {
|
||||
use libc::SIGCONT;
|
||||
|
||||
self.signal(SIGCONT);
|
||||
}
|
||||
|
||||
fn signal(&self, sig: c_int) {
|
||||
use libc::*;
|
||||
|
||||
extern "C" {
|
||||
fn killpg(pgrp: pid_t, sig: c_int) -> c_int;
|
||||
}
|
||||
|
@ -111,6 +101,10 @@ mod imp {
|
|||
|
||||
}
|
||||
|
||||
pub fn terminate(&self) {
|
||||
self.signal(SIGTERM);
|
||||
}
|
||||
|
||||
pub fn wait(&self) {
|
||||
use nix::sys::wait::waitpid;
|
||||
|
||||
|
@ -181,9 +175,7 @@ mod imp {
|
|||
}
|
||||
|
||||
pub fn kill(&self) {
|
||||
unsafe {
|
||||
let _ = TerminateJobObject(self.job, 1);
|
||||
}
|
||||
self.terminate();
|
||||
}
|
||||
|
||||
pub fn pause(&self) {
|
||||
|
@ -192,6 +184,13 @@ mod imp {
|
|||
pub fn resume(&self) {
|
||||
}
|
||||
|
||||
pub fn terminate(&self) {
|
||||
unsafe {
|
||||
let _ = TerminateJobObject(self.job, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn wait(&self) {
|
||||
unsafe {
|
||||
let _ = WaitForSingleObject(self.job, INFINITE);
|
||||
|
|
Loading…
Reference in New Issue