diff options
author | Rory Dudley | 2024-02-24 21:24:19 -0700 |
---|---|---|
committer | Rory Dudley | 2024-02-24 21:24:19 -0700 |
commit | b6fc81066cfcc29d4519191eae5ba19581ad2774 (patch) | |
tree | b11eb5bd076e672812f94ba8578e80769c02f86f | |
parent | 536e250653e5c140a6d9e60f1cd652b79135e7a6 (diff) | |
download | dwarvish-signal.tar.gz |
Replace ctrlc with signal-hooksignal
Replaced the 'ctrlc' crate with 'signal-hook' for handling of SIGINT.
The 'signal_hook::low_level::register' function is actually unsafe.
However, according to
https://docs.rs/signal-hook/latest/signal_hook/low_level/fn.register.html,
it is only unsafe in the case of multithreaded applications. There are
some race conditions as well. For instance, it appears that even when we
fork to a child process, SIGINT is captured on both that process, as
well as the shell.
Notes
Notes:
The replacement was motivated by the fact that 'ctrlc' appears to use a
separate thread to handle interrupts. This is evident if you run:
ps aux | grep dwvsh
USER PID %CPU %MEM VSZ RSS TTY STAT START COMMAND
user pid 0.0 0.0 71500 3072 term Sl+ 20:08 target/debug/dwvsh
Further reading in 'man ps' under 'PROCESS STATE CODES', reveals that 'l'
is a process state referring to multithreaded applications.
Given the nature of interupts, this seems unnecessary.
The issue where SIGINT is captured by both the shell, and child process
will have to be addressed.
-rw-r--r-- | Cargo.lock | 98 | ||||
-rw-r--r-- | Cargo.toml | 4 | ||||
-rw-r--r-- | src/main.rs | 14 |
3 files changed, 17 insertions, 99 deletions
@@ -3,32 +3,10 @@ version = 3 [[package]] -name = "bitflags" -version = "2.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "ctrlc" -version = "3.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b467862cc8610ca6fc9a1532d7777cee0804e678ab45410897b9396495994a0b" -dependencies = [ - "nix", - "windows-sys", -] - -[[package]] name = "dwarvish" version = "0.0.0" dependencies = [ - "ctrlc", + "signal-hook", ] [[package]] @@ -38,78 +16,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] -name = "nix" -version = "0.27.1" +name = "signal-hook" +version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" +checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" dependencies = [ - "bitflags", - "cfg-if", "libc", + "signal-hook-registry", ] [[package]] -name = "windows-sys" -version = "0.52.0" +name = "signal-hook-registry" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "libc", ] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" @@ -9,7 +9,5 @@ description = "A POSIX compliance shell and tiny functional programming language name = "dwvsh" path = "src/main.rs" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] -ctrlc = "3.4.2" +signal-hook = "0.3.17" diff --git a/src/main.rs b/src/main.rs index db349d3..986e006 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,4 @@ mod recite; -use ctrlc; use recite::path::prefresh; use recite::Poem; use std::io::{self, Write}; @@ -28,7 +27,6 @@ fn repl(path: &Vec<&Path>, prompt: &str) { // Main shell loop loop { // Output the prompt - io::stdout().flush().unwrap(); print!("{}", prompt); io::stdout().flush().unwrap(); @@ -83,11 +81,13 @@ fn main() { let prompt = "|> "; // Handle signals - ctrlc::set_handler(move || { - print!("\n{}", prompt); - io::stdout().flush().unwrap(); - }) - .expect("dwvsh: signals: unable to set sigint handler"); + unsafe { + signal_hook::low_level::register(signal_hook::consts::SIGINT, move || { + print!("\n{}", prompt); + io::stdout().flush().unwrap(); + }) + .unwrap(); + }; // Begin evaluating commands repl(&path, prompt); |