mirror of
https://github.com/astral-sh/uv.git
synced 2025-10-27 18:36:44 +00:00
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:
parent
20018cd0fc
commit
82f4864386
3 changed files with 12 additions and 1 deletions
|
|
@ -138,7 +138,7 @@ tempfile = { version = "3.9.0" }
|
||||||
textwrap = { version = "0.16.1" }
|
textwrap = { version = "0.16.1" }
|
||||||
thiserror = { version = "1.0.56" }
|
thiserror = { version = "1.0.56" }
|
||||||
tl = { version = "0.7.7" }
|
tl = { version = "0.7.7" }
|
||||||
tokio = { version = "1.35.1", features = ["fs", "io-util", "macros", "process", "sync"] }
|
tokio = { version = "1.35.1", features = ["fs", "io-util", "macros", "process", "signal", "sync"] }
|
||||||
tokio-stream = { version = "0.1.14" }
|
tokio-stream = { version = "0.1.14" }
|
||||||
tokio-tar = { version = "0.3.1" }
|
tokio-tar = { version = "0.3.1" }
|
||||||
tokio-util = { version = "0.7.10", features = ["compat"] }
|
tokio-util = { version = "0.7.10", features = ["compat"] }
|
||||||
|
|
|
||||||
|
|
@ -471,6 +471,12 @@ pub(crate) async fn run(
|
||||||
command.executable().to_string_lossy()
|
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")?;
|
let status = handle.wait().await.context("Child process disappeared")?;
|
||||||
|
|
||||||
// Exit based on the result of the command
|
// Exit based on the result of the command
|
||||||
|
|
|
||||||
|
|
@ -185,6 +185,11 @@ pub(crate) async fn run(
|
||||||
}
|
}
|
||||||
.with_context(|| format!("Failed to spawn: `{}`", executable.to_string_lossy()))?;
|
.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")?;
|
let status = handle.wait().await.context("Child process disappeared")?;
|
||||||
|
|
||||||
// Exit based on the result of the command
|
// Exit based on the result of the command
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue