chore: clean diagnostics; brush login+shell fix (validated cwd)
This commit is contained in:
@@ -1,3 +1,55 @@
|
||||
diff --git a/brush-interactive/src/minimal/input_backend.rs b/brush-interactive/src/minimal/input_backend.rs
|
||||
index 48732fb..d0026db 100644
|
||||
--- a/brush-interactive/src/minimal/input_backend.rs
|
||||
+++ b/brush-interactive/src/minimal/input_backend.rs
|
||||
@@ -48,15 +48,38 @@ impl MinimalInputBackend {
|
||||
}
|
||||
|
||||
fn read_input_line() -> Result<ReadResult, ShellError> {
|
||||
- let mut input = String::new();
|
||||
- let bytes_read = std::io::stdin()
|
||||
- .read_line(&mut input)
|
||||
- .map_err(ShellError::InputError)?;
|
||||
-
|
||||
- if bytes_read == 0 {
|
||||
- Ok(ReadResult::Eof)
|
||||
- } else {
|
||||
- Ok(ReadResult::Input(input))
|
||||
+ // On Redox the interactive console is a pty slave whose reads can
|
||||
+ // return Ok(0) with no bytes even though the master side is still open
|
||||
+ // (e.g. a non-blocking read with no data currently queued). std's
|
||||
+ // `read_line` reports that as end-of-input; if the shell treated it as
|
||||
+ // EOF it would exit immediately and getty would respawn login in a
|
||||
+ // tight loop. Distinguish a *spurious* empty read (retry, briefly
|
||||
+ // yielding to avoid a busy spin) from a real terminal by only treating
|
||||
+ // 0 bytes as EOF when stdin is not a tty.
|
||||
+ use std::io::ErrorKind;
|
||||
+ loop {
|
||||
+ let mut input = String::new();
|
||||
+ match std::io::stdin().read_line(&mut input) {
|
||||
+ // Got a line.
|
||||
+ Ok(n) if n != 0 => return Ok(ReadResult::Input(input)),
|
||||
+ // Zero bytes: real EOF only on a non-interactive input. On an
|
||||
+ // interactive Redox pty a non-blocking read with no data queued
|
||||
+ // can also surface as Ok(0); retry rather than exiting (which
|
||||
+ // would drop back to a getty login loop).
|
||||
+ Ok(_) => {
|
||||
+ if !std::io::stdin().is_terminal() {
|
||||
+ return Ok(ReadResult::Eof);
|
||||
+ }
|
||||
+ }
|
||||
+ // A non-blocking read with no data currently available (or an
|
||||
+ // interrupted syscall) is not fatal on an interactive terminal;
|
||||
+ // keep polling for input.
|
||||
+ Err(e)
|
||||
+ if std::io::stdin().is_terminal()
|
||||
+ && matches!(e.kind(), ErrorKind::WouldBlock | ErrorKind::Interrupted) => {}
|
||||
+ Err(e) => return Err(ShellError::InputError(e)),
|
||||
+ }
|
||||
+ std::thread::sleep(std::time::Duration::from_millis(20));
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/brush-shell/src/entry.rs b/brush-shell/src/entry.rs
|
||||
index 15340ad..384f0ca 100644
|
||||
--- a/brush-shell/src/entry.rs
|
||||
|
||||
+1
-1
Submodule local/sources/base updated: d20557f726...75229a5789
+1
-1
Submodule local/sources/relibc updated: 20d4e8746f...c6f8a2c208
+1
-1
Submodule local/sources/userutils updated: fbbb1d88cb...b0cfab717e
Reference in New Issue
Block a user