Skip to content

Commit 1be29d3

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 bebab7e commit 1be29d3

File tree

3 files changed

+22
-43
lines changed

3 files changed

+22
-43
lines changed

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: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -145,17 +145,30 @@ 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+
if unsafe { SetConsoleCtrlHandler(Some(ctrlc_handler), TRUE) } == FALSE {
170+
anyhow::bail!("failed to set ctrl-c handler");
171+
}
159172

160173
let exit = cmd
161174
.spawn()

0 commit comments

Comments
 (0)