Skip to content

Commit

Permalink
fix: Propagate signals in project run
Browse files Browse the repository at this point in the history
  • Loading branch information
shaneikennedy committed Nov 8, 2024
1 parent 9db785b commit 091ca23
Showing 1 changed file with 23 additions and 2 deletions.
25 changes: 23 additions & 2 deletions crates/uv/src/commands/project/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ use futures::StreamExt;
use itertools::Itertools;
use owo_colors::OwoColorize;
use tokio::process::Command;
use tokio::select;
use tokio::signal::unix::{signal, SignalKind};
use tracing::{debug, warn};
use url::Url;
use uv_cache::Cache;
Expand Down Expand Up @@ -994,9 +996,28 @@ pub(crate) async fn run(
// Ignore signals in the parent process, deferring them to the child. This is safe as long as
// the command is the last thing that runs in this process; otherwise, we'd need to restore the
// signal handlers after the command completes.
let _handler = tokio::spawn(async { while tokio::signal::ctrl_c().await.is_ok() {} });
let mut term_signal = signal(SignalKind::terminate())?;
let mut int_signal = signal(SignalKind::interrupt())?;

let status = handle.wait().await.context("Child process disappeared")?;
let status = select! {
status = handle.wait() => status,

// `SIGTERM`
_ = term_signal.recv() => {
handle.kill().await?;
handle.wait().await.context("Child process disappeared")?;
return Ok(ExitStatus::Failure);
}

// `SIGINT`
_ = int_signal.recv() => {
handle.kill().await?;
handle.wait().await.context("Child process disappeared")?;
return Ok(ExitStatus::Failure);
}
};

let status = status.context("Child process disappeared")?;

// Exit based on the result of the command
if let Some(code) = status.code() {
Expand Down

0 comments on commit 091ca23

Please sign in to comment.