Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,14 @@ pub struct CommonOpts {
#[clap(long)]
pub kill_process_tree: bool,

/// Abort shawl if ctrl-C or ctrl-Break is received unexpectedly.
/// Use this when running shawl directly from a terminal so that Ctrl+C stops it.
/// Or if you expect shawl to handle those ctrl c.
/// Using this as a service means that, when the service or the child receive ctrl c,
/// it may throw an STACK_BUFFER_OVERRUN error to windows
#[clap(long)]
pub interactive: bool,

/// Command to run as a service
#[clap(required(true), last(true))]
pub command: Vec<String>,
Expand Down Expand Up @@ -974,6 +982,23 @@ speculate::speculate! {
);
}

it "accepts --interactive" {
check_args(
&["shawl", "run", "--interactive", "--", "foo"],
Cli {
sub: Subcommand::Run {
name: s("Shawl"),
cwd: None,
common: CommonOpts {
interactive: true,
command: vec![s("foo")],
..Default::default()
}
}
},
);
}

it "accepts --env" {
check_args(
&["shawl", "add", "--env", "FOO=bar", "--name", "foo", "--", "foo"],
Expand Down
17 changes: 17 additions & 0 deletions src/control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,9 @@ fn construct_shawl_run_args(name: &str, cwd: &Option<String>, opts: &CommonOpts)
if opts.kill_process_tree {
shawl_args.push("--kill-process-tree".to_string());
}
if opts.interactive {
shawl_args.push("--interactive".to_string());
}
shawl_args
}

Expand Down Expand Up @@ -600,6 +603,20 @@ speculate::speculate! {
vec!["run", "--name", "shawl", "--kill-process-tree"],
);
}

it "handles --interactive" {
assert_eq!(
construct_shawl_run_args(
&s("shawl"),
&None,
&CommonOpts {
interactive: true,
..Default::default()
}
),
vec!["run", "--name", "shawl", "--interactive"],
);
}
}

describe "prepare_command" {
Expand Down
3 changes: 2 additions & 1 deletion src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,13 @@ pub fn run_service(start_arguments: Vec<std::ffi::OsString>) -> windows_service:
};
let pass = &opts.pass.unwrap_or_else(|| vec![0]);
let stop_timeout = &opts.stop_timeout.unwrap_or(3000_u64);
let interactive = opts.interactive;
let mut service_exit_code = ServiceExitCode::NO_ERROR;

let ignore_ctrlc = std::sync::Arc::new(std::sync::atomic::AtomicBool::new(false));
let ignore_ctrlc2 = ignore_ctrlc.clone();
ctrlc::set_handler(move || {
if !ignore_ctrlc2.load(std::sync::atomic::Ordering::SeqCst) {
if interactive && !ignore_ctrlc2.load(std::sync::atomic::Ordering::SeqCst) {
std::process::abort();
}
})
Expand Down
Loading