Skip to content

Commit fb2225a

Browse files
committed
feat: replace ctrlc with manual syscalls
The `ctrlc` library uses a semaphore in its handler on windows, which we do not need since we're not doing anything with the handler except suppressing the default behavior. This replaces the library with the direcy syscalls to set a console control handler that does nothing, without a semaphore.
1 parent 44c2fbe commit fb2225a

4 files changed

Lines changed: 29 additions & 43 deletions

File tree

.github/workflows/ci.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ jobs:
4343
- macos-latest
4444
- windows-latest
4545
rust:
46+
- '1.86'
47+
- '1.87'
48+
- '1.88'
49+
- '1.89'
50+
- '1.90'
4651
- stable
4752
- beta
4853
- nightly

Cargo.lock

Lines changed: 1 addition & 36 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/git-remote-codecommit/Cargo.toml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,6 @@ tracing = "0.1.41"
3232
tracing-subscriber = { version = "0.3.20", features = ["env-filter"] }
3333
uriparse = "0.6.4"
3434

35-
[target."cfg(windows)".dependencies]
36-
ctrlc = "3.5.0"
35+
[target."cfg(windows)".dependencies.windows-sys]
36+
version = "0.61.2"
37+
features = ["Win32_Foundation", "Win32_System_Console"]

crates/git-remote-codecommit/src/main.rs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -145,17 +145,32 @@ fn exec_replace(mut cmd: std::process::Command) -> anyhow::Result<ExitCode> {
145145

146146
#[cfg(windows)]
147147
fn exec_replace(mut cmd: std::process::Command) -> anyhow::Result<ExitCode> {
148+
#![expect(unsafe_code)]
149+
use windows_sys::Win32::Foundation::FALSE;
150+
use windows_sys::Win32::Foundation::TRUE;
151+
use windows_sys::Win32::System::Console::SetConsoleCtrlHandler;
152+
use windows_sys::core::BOOL;
153+
148154
use crate::nightly::ExitCodeExt;
149155

156+
unsafe extern "system" fn ctrlc_handler(_: u32) -> BOOL {
157+
// Do nothing; let the child process handle it.
158+
TRUE
159+
}
160+
150161
// windows and other non-unix platforms don't support `execvp`, so we can't
151162
// replace the current process. Instead, we need to spawn a new process and
152163
// set up the pipes.
153164

154-
// We setup a ctrlc handler and ignore it because on windows, this signal is
155-
// sent to all processes attached to the console, including the parent
156-
// process. Therefore, by ignoring the ctrl-c, we let the child handle the
157-
// signal and exit. We can reap the process normally.
158-
ctrlc::set_handler(|| {}).context("failed to set ctrl-c handler")?;
165+
// SAFETY: We setup a ctrlc handler and ignore it because on windows, this
166+
// signal is sent to all processes attached to the console, including the
167+
// parent process. Therefore, by ignoring the ctrl-c, we let the child
168+
// handle the signal and exit. We can reap the process normally.
169+
unsafe {
170+
if SetConsoleCtrlHandler(Some(ctrlc_handler), TRUE) == FALSE {
171+
anyhow::bail!("failed to set ctrl-c handler");
172+
}
173+
}
159174

160175
let exit = cmd
161176
.spawn()

0 commit comments

Comments
 (0)