Skip to content

Commit

Permalink
Explicitly handle ctrl-c to restore cursor (astral-sh#564)
Browse files Browse the repository at this point in the history
  • Loading branch information
mitsuhiko authored and j178 committed Feb 18, 2024
1 parent faefd30 commit 27c15c6
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 13 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ _Unreleased_
- Added `rye fmt` and `rye lint` commands to format and lint with
the help of Ruff. #555

- Restore cursor state on Ctrl-C. This fixes some issues where in rare cases the
cursor would disappear even after shutting down rye. #564

<!-- released start -->

## 0.19.0
Expand Down
11 changes: 11 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions rye/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ monotrail-utils = { git = "https://github.com/konstin/poc-monotrail", version =
python-pkginfo = { version = "0.6.0", features = ["serde"] }
sysinfo = { version = "0.29.4", default-features = false, features = [] }
home = "0.5.9"
ctrlc = "3.4.2"

[target."cfg(unix)".dependencies]
whattheshell = "1.0.1"
Expand Down
20 changes: 20 additions & 0 deletions rye/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,33 @@ mod sync;
mod utils;

static SHOW_CONTINUE_PROMPT: AtomicBool = AtomicBool::new(false);
static DISABLE_CTRLC_HANDLER: AtomicBool = AtomicBool::new(false);

/// Changes the shutdown behavior to request a continue prompt.
pub fn request_continue_prompt() {
SHOW_CONTINUE_PROMPT.store(true, Ordering::Relaxed);
}

/// Disables the ctrl-c handler
pub fn disable_ctrlc_handler() {
DISABLE_CTRLC_HANDLER.store(true, Ordering::Relaxed);
}

pub fn main() {
ctrlc::set_handler(move || {
if !DISABLE_CTRLC_HANDLER.load(Ordering::Relaxed) {
let term = console::Term::stderr();
term.show_cursor().ok();
term.flush().ok();
std::process::exit(if cfg!(windows) {
0xC000013Au32 as i32
} else {
130
});
}
})
.unwrap();

let result = cli::execute();
let status = match result {
Ok(()) => 0,
Expand Down
16 changes: 3 additions & 13 deletions rye/src/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,9 @@ pub fn unpack_archive(contents: &[u8], dst: &Path, strip_components: usize) -> R

/// Spawns a command exec style.
pub fn exec_spawn(cmd: &mut Command) -> Result<Infallible, Error> {
// this is technically only necessary on windows
crate::disable_ctrlc_handler();

#[cfg(unix)]
{
use std::os::unix::process::CommandExt;
Expand All @@ -270,19 +273,6 @@ pub fn exec_spawn(cmd: &mut Command) -> Result<Infallible, Error> {
}
#[cfg(windows)]
{
use winapi::shared::minwindef::{BOOL, DWORD, FALSE, TRUE};
use winapi::um::consoleapi::SetConsoleCtrlHandler;

unsafe extern "system" fn ctrlc_handler(_: DWORD) -> BOOL {
// Do nothing. Let the child process handle it.
TRUE
}
unsafe {
if SetConsoleCtrlHandler(Some(ctrlc_handler), TRUE) == FALSE {
return Err(anyhow!("unable to set console handler"));
}
}

cmd.stdin(Stdio::inherit());
let status = cmd.status()?;
std::process::exit(status.code().unwrap())
Expand Down

0 comments on commit 27c15c6

Please sign in to comment.