diff options
Diffstat (limited to 'shell')
| -rw-r--r-- | shell/src/lib.rs | 58 |
1 files changed, 38 insertions, 20 deletions
diff --git a/shell/src/lib.rs b/shell/src/lib.rs index f2a0e6e..d1710cc 100644 --- a/shell/src/lib.rs +++ b/shell/src/lib.rs | |||
| @@ -30,7 +30,9 @@ use alloc::vec::Vec; | |||
| 30 | use rsnix::tty::{self, LineInput}; | 30 | use rsnix::tty::{self, LineInput}; |
| 31 | use rsnix::{gop_print, gop_println}; | 31 | use rsnix::{gop_print, gop_println}; |
| 32 | 32 | ||
| 33 | /// Run the shell forever. | 33 | /// Run the home-terminal shell (task 0). The home terminal is an |
| 34 | /// ordinary WM window (id 0) owned by this task, so input flows through | ||
| 35 | /// the same pumped queue as any windowed shell. | ||
| 34 | pub fn run() -> ! { | 36 | pub fn run() -> ! { |
| 35 | // Row 0 is the boot-marker status line (white-on-black, the last boot | 37 | // Row 0 is the boot-marker status line (white-on-black, the last boot |
| 36 | // stage drawn during init). Real hardware has no serial console, so | 38 | // stage drawn during init). Real hardware has no serial console, so |
| @@ -64,6 +66,7 @@ pub fn run() -> ! { | |||
| 64 | } | 66 | } |
| 65 | term_println("!!! end of crash report"); | 67 | term_println("!!! end of crash report"); |
| 66 | } | 68 | } |
| 69 | let term = rsnix::vt::home_terminal(); | ||
| 67 | 70 | ||
| 68 | loop { | 71 | loop { |
| 69 | // Push any deferred scrolls so the prompt renders on a current | 72 | // Push any deferred scrolls so the prompt renders on a current |
| @@ -77,12 +80,18 @@ pub fn run() -> ! { | |||
| 77 | } | 80 | } |
| 78 | // Print prompt | 81 | // Print prompt |
| 79 | term_print("> "); | 82 | term_print("> "); |
| 80 | 83 | // Read one line (tty canonical mode over the pumped queue). | |
| 81 | // Read one line from keyboard (tty canonical mode) | 84 | match tty::read_line(term) { |
| 82 | match tty::read_line() { | 85 | None => { |
| 83 | LineInput::Interrupted => continue, // ^C - fresh prompt | 86 | // Window 0 is never closed; a Close message here means |
| 84 | LineInput::Eof => continue, // ^D on an empty line - fresh prompt (no poweroff) | 87 | // shutdown. Park forever (the idle task takes over). |
| 85 | LineInput::Line(line) => { | 88 | loop { |
| 89 | rsnix::sched::sleep_ms(1000); | ||
| 90 | } | ||
| 91 | } | ||
| 92 | Some(LineInput::Interrupted) => continue, // ^C - fresh prompt | ||
| 93 | Some(LineInput::Eof) => continue, // ^D - fresh prompt (no poweroff) | ||
| 94 | Some(LineInput::Line(line)) => { | ||
| 86 | let trimmed = line.trim(); | 95 | let trimmed = line.trim(); |
| 87 | if trimmed.is_empty() { | 96 | if trimmed.is_empty() { |
| 88 | continue; | 97 | continue; |
| @@ -94,15 +103,14 @@ pub fn run() -> ! { | |||
| 94 | } | 103 | } |
| 95 | 104 | ||
| 96 | /// Run a shell instance inside a windowed terminal. Same as `run()` but | 105 | /// Run a shell instance inside a windowed terminal. Same as `run()` but |
| 97 | /// reads from the task's message queue (Fed by the WM input pump) and | 106 | /// for a spawned F1 terminal (own task + window). |
| 98 | /// writes to the active terminal (set by the caller via `vt::set_active`). | ||
| 99 | /// Returns when the window is closed (Close message or ^D on empty line). | 107 | /// Returns when the window is closed (Close message or ^D on empty line). |
| 100 | pub fn run_windowed(term: &mut rsnix::vt::Terminal) { | 108 | pub fn run_windowed(term: &mut rsnix::vt::Terminal) { |
| 101 | term_println(&alloc::format!("rs-dos v{}", env!("CARGO_PKG_VERSION"))); | 109 | term_println(&alloc::format!("rs-dos v{}", env!("CARGO_PKG_VERSION"))); |
| 102 | loop { | 110 | loop { |
| 103 | rsnix::vt::sync_scroll(); | 111 | rsnix::vt::sync_scroll(); |
| 104 | term_print("> "); | 112 | term_print("> "); |
| 105 | match tty::read_line_from_queue(term) { | 113 | match tty::read_line(term) { |
| 106 | None => return, // window closed | 114 | None => return, // window closed |
| 107 | Some(LineInput::Interrupted) => continue, | 115 | Some(LineInput::Interrupted) => continue, |
| 108 | Some(LineInput::Eof) => return, // ^D in windowed mode = close | 116 | Some(LineInput::Eof) => return, // ^D in windowed mode = close |
| @@ -1033,9 +1041,11 @@ fn cmd_cat(p: &Parsed) { | |||
| 1033 | /// Read lines from the tty until ^C/^D (or an exact marker line, when | 1041 | /// Read lines from the tty until ^C/^D (or an exact marker line, when |
| 1034 | /// `marker` is Some - the marker itself is not part of the input). | 1042 | /// `marker` is Some - the marker itself is not part of the input). |
| 1035 | fn cat_stdin(pipe: &mut Pipeline, marker: Option<&str>) -> bool { | 1043 | fn cat_stdin(pipe: &mut Pipeline, marker: Option<&str>) -> bool { |
| 1044 | let term = rsnix::vt::home_terminal(); | ||
| 1036 | loop { | 1045 | loop { |
| 1037 | match tty::read_line() { | 1046 | match tty::read_line(term) { |
| 1038 | LineInput::Line(l) => { | 1047 | None => return true, // window closed = EOF |
| 1048 | Some(LineInput::Line(l)) => { | ||
| 1039 | if marker.is_some() && l.as_str() == marker.unwrap() { | 1049 | if marker.is_some() && l.as_str() == marker.unwrap() { |
| 1040 | return true; | 1050 | return true; |
| 1041 | } | 1051 | } |
| @@ -1043,8 +1053,8 @@ fn cat_stdin(pipe: &mut Pipeline, marker: Option<&str>) -> bool { | |||
| 1043 | return false; | 1053 | return false; |
| 1044 | } | 1054 | } |
| 1045 | } | 1055 | } |
| 1046 | LineInput::Interrupted => return false, // ^C aborts the stream | 1056 | Some(LineInput::Interrupted) => return false, // ^C aborts the stream |
| 1047 | LineInput::Eof => return true, // ^D = EOF | 1057 | Some(LineInput::Eof) => return true, // ^D = EOF |
| 1048 | } | 1058 | } |
| 1049 | } | 1059 | } |
| 1050 | } | 1060 | } |
| @@ -1280,9 +1290,11 @@ fn hexdump_stdin(pipe: &mut Pipeline, marker: Option<&str>) { | |||
| 1280 | row_len: 0, | 1290 | row_len: 0, |
| 1281 | alive: true, | 1291 | alive: true, |
| 1282 | }; | 1292 | }; |
| 1293 | let term = rsnix::vt::home_terminal(); | ||
| 1283 | loop { | 1294 | loop { |
| 1284 | match tty::read_line() { | 1295 | match tty::read_line(term) { |
| 1285 | LineInput::Line(l) => { | 1296 | None => break, |
| 1297 | Some(LineInput::Line(l)) => { | ||
| 1286 | if marker.is_some() && l.as_str() == marker.unwrap() { | 1298 | if marker.is_some() && l.as_str() == marker.unwrap() { |
| 1287 | break; | 1299 | break; |
| 1288 | } | 1300 | } |
| @@ -1295,8 +1307,8 @@ fn hexdump_stdin(pipe: &mut Pipeline, marker: Option<&str>) { | |||
| 1295 | break; | 1307 | break; |
| 1296 | } | 1308 | } |
| 1297 | } | 1309 | } |
| 1298 | LineInput::Interrupted => break, | 1310 | Some(LineInput::Interrupted) => break, |
| 1299 | LineInput::Eof => break, | 1311 | Some(LineInput::Eof) => break, |
| 1300 | } | 1312 | } |
| 1301 | } | 1313 | } |
| 1302 | ctx.flush(); | 1314 | ctx.flush(); |
| @@ -1429,7 +1441,11 @@ fn cmd_draw(_p: &Parsed) { | |||
| 1429 | 1441 | ||
| 1430 | fn cmd_term(_p: &Parsed) { | 1442 | fn cmd_term(_p: &Parsed) { |
| 1431 | // Debug: check if the callback is registered. | 1443 | // Debug: check if the callback is registered. |
| 1432 | let cb_set = unsafe { core::ptr::addr_of!(rsnix::wm::SPAWN_TERMINAL_CB).read().is_some() }; | 1444 | let cb_set = unsafe { |
| 1445 | core::ptr::addr_of!(rsnix::wm::SPAWN_TERMINAL_CB) | ||
| 1446 | .read() | ||
| 1447 | .is_some() | ||
| 1448 | }; | ||
| 1433 | term_println(&alloc::format!("term: SPAWN_TERMINAL_CB set = {}", cb_set)); | 1449 | term_println(&alloc::format!("term: SPAWN_TERMINAL_CB set = {}", cb_set)); |
| 1434 | if !cb_set { | 1450 | if !cb_set { |
| 1435 | term_err("term: callback not registered — cannot spawn"); | 1451 | term_err("term: callback not registered — cannot spawn"); |
| @@ -1441,7 +1457,9 @@ fn cmd_term(_p: &Parsed) { | |||
| 1441 | let h = 400usize.min(ch); | 1457 | let h = 400usize.min(ch); |
| 1442 | term_println(&alloc::format!("term: requesting window {}x{}", w, h)); | 1458 | term_println(&alloc::format!("term: requesting window {}x{}", w, h)); |
| 1443 | unsafe { | 1459 | unsafe { |
| 1444 | let cb = core::ptr::addr_of!(rsnix::wm::SPAWN_TERMINAL_CB).read().unwrap(); | 1460 | let cb = core::ptr::addr_of!(rsnix::wm::SPAWN_TERMINAL_CB) |
| 1461 | .read() | ||
| 1462 | .unwrap(); | ||
| 1445 | cb("term dbg", w, h); | 1463 | cb("term dbg", w, h); |
| 1446 | } | 1464 | } |
| 1447 | term_println("term: callback returned (task should be spawning)"); | 1465 | term_println("term: callback returned (task should be spawning)"); |
