From 43c44ae6fe7dbfcf6af3e5e53c29f65bbf94c9c2 Mon Sep 17 00:00:00 2001 From: salmonik Date: Fri, 31 Jul 2026 16:43:04 +0200 Subject: shell: ^C cancels the line / aborts streams, ^D = EOF → poweroff MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ps2: Ctrl+C and Ctrl+D are now KeyEvents (ctrl modifier + c/d map); other Ctrl+key combos are swallowed - shell read_line: ^C clears the line and echoes '^C' (bash-style), ^D on an empty line echoes '^D' and shuts down (EOF), ^D with text on the line is ignored - cat/hexdump stream incrementally (was: build whole string then print) and check for ^C between chunks, so a running dump can be aborted - verified in QEMU: line cancel, standalone interrupt, ^C aborts an infinite 'cat /dev/zero' stream, ^D powers off --- rsnix/src/fs.rs | 32 ++++++++++++++++++++++---------- rsnix/src/ps2.rs | 11 +++++++++++ 2 files changed, 33 insertions(+), 10 deletions(-) (limited to 'rsnix') diff --git a/rsnix/src/fs.rs b/rsnix/src/fs.rs index 56820bb..95a84bf 100644 --- a/rsnix/src/fs.rs +++ b/rsnix/src/fs.rs @@ -15,14 +15,14 @@ extern crate alloc; -use alloc::boxed::Box; -use alloc::string::String; -use alloc::vec::Vec; use crate::gop; use crate::memory; use crate::pci; use crate::rtc; use crate::serial; +use alloc::boxed::Box; +use alloc::string::String; +use alloc::vec::Vec; /// /dev/mem covers the low physical-memory window (identity-mapped RAM). pub const MEM_WINDOW: u64 = 64 * 1024; @@ -96,9 +96,24 @@ pub fn init() -> (usize, usize) { let _tmp = add("tmp", Some(root), FileType::Dir, NodeData::Dir(Vec::new())); let etc = add("etc", Some(root), FileType::Dir, NodeData::Dir(Vec::new())); - add("mem", Some(dev), FileType::Char, NodeData::Char(CharDevice::Mem)); - add("rtc", Some(dev), FileType::Char, NodeData::Char(CharDevice::Rtc)); - add("pci", Some(dev), FileType::Char, NodeData::Char(CharDevice::Pci)); + add( + "mem", + Some(dev), + FileType::Char, + NodeData::Char(CharDevice::Mem), + ); + add( + "rtc", + Some(dev), + FileType::Char, + NodeData::Char(CharDevice::Rtc), + ); + add( + "pci", + Some(dev), + FileType::Char, + NodeData::Char(CharDevice::Pci), + ); add( "version", Some(dev), @@ -146,10 +161,7 @@ pub fn init() -> (usize, usize) { ), ); - let dirs = nodes() - .iter() - .filter(|n| n.kind == FileType::Dir) - .count(); + let dirs = nodes().iter().filter(|n| n.kind == FileType::Dir).count(); let files = nodes().len() - dirs; (dirs, files) } diff --git a/rsnix/src/ps2.rs b/rsnix/src/ps2.rs index 477d146..1b10b3b 100644 --- a/rsnix/src/ps2.rs +++ b/rsnix/src/ps2.rs @@ -22,6 +22,8 @@ pub enum KeyEvent { Backspace, Tab, Escape, + CtrlC, + CtrlD, ArrowUp, ArrowDown, ArrowLeft, @@ -304,6 +306,15 @@ fn process_byte(byte: u8) -> Option { ch.to_ascii_uppercase() }; } + // Ctrl+letter — the shell uses ^C (interrupt) and ^D (EOF). + let ctrl = state.modifiers & (MOD_LCTRL | MOD_RCTRL) != 0; + if ctrl { + return match ch.to_ascii_lowercase() { + b'c' => Some(KeyEvent::CtrlC), + b'd' => Some(KeyEvent::CtrlD), + _ => None, // swallow other Ctrl+key combinations + }; + } if ch != 0 { Some(KeyEvent::Char(ch as char)) } else { -- cgit v1.2.3