Ignore Ctrl-C signals in uv run and uv tool run (#5395)

## Summary

This is a bit simpler than #5333, but seems to work in my testing on
macOS and Windows. It's based on implementations that I found in
[Pixi](36f1bb297d/src/cli/exec.rs (L99))
and
[Wasmer](49e60af8df/lib/wasix/src/state/builder.rs (L1058)).

Closes https://github.com/astral-sh/uv/issues/5257.

## Test Plan

On both macOS and Windows:

- `cargo run -- tool run --from jupyterlab jupyter-lab` -- hit Ctrl-C;
verify that the process exits and the terminal is left in a good state.
- `cargo run -- run python` -- hit Ctrl-C; verify that the process does
_not_ exit, but does on Ctrl-D.
This commit is contained in:
Charlie Marsh 2024-07-24 08:33:10 -04:00 committed by GitHub
parent 20018cd0fc
commit 82f4864386
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 12 additions and 1 deletions

View file

@ -471,6 +471,12 @@ pub(crate) async fn run(
command.executable().to_string_lossy()
)
})?;
// 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 status = handle.wait().await.context("Child process disappeared")?;
// Exit based on the result of the command

View file

@ -185,6 +185,11 @@ pub(crate) async fn run(
}
.with_context(|| format!("Failed to spawn: `{}`", executable.to_string_lossy()))?;
// 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 status = handle.wait().await.context("Child process disappeared")?;
// Exit based on the result of the command