summaryrefslogtreecommitdiffstats
path: root/shell/src
diff options
context:
space:
mode:
Diffstat (limited to 'shell/src')
-rw-r--r--shell/src/lib.rs58
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;
30use rsnix::tty::{self, LineInput}; 30use rsnix::tty::{self, LineInput};
31use rsnix::{gop_print, gop_println}; 31use 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.
34pub fn run() -> ! { 36pub 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).
100pub fn run_windowed(term: &mut rsnix::vt::Terminal) { 108pub 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).
1035fn cat_stdin(pipe: &mut Pipeline, marker: Option<&str>) -> bool { 1043fn 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
1430fn cmd_term(_p: &Parsed) { 1442fn 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)");