diff --git a/src/bin/getty.rs b/src/bin/getty.rs index b1d85317ff..99d042b978 100644 --- a/src/bin/getty.rs +++ b/src/bin/getty.rs @@ -48,6 +48,14 @@ AUTHOR const DEFAULT_COLS: u16 = 80; const DEFAULT_LINES: u16 = 30; +// Plausibility bounds for the cursor-report size probe (see `daemon`). The +// probe is unreliable on the fbcond console, so anything outside this range is +// treated as a bad reading and replaced with the safe defaults above. +const MIN_PLAUSIBLE_COLS: u16 = 40; +const MAX_PLAUSIBLE_COLS: u16 = 1000; +const MIN_PLAUSIBLE_LINES: u16 = 10; +const MAX_PLAUSIBLE_LINES: u16 = 1000; + pub fn handle( event_queue: &mut RawEventQueue, tty_fd: RawFd, @@ -225,7 +233,24 @@ fn tty_columns_lines(tty: &mut File) -> Result<(u16, u16), Box> { } fn daemon(tty: &mut File, clear: bool, contain: bool, stderr: &mut Stderr) { - let (columns, lines) = tty_columns_lines(tty).unwrap_or((DEFAULT_COLS, DEFAULT_LINES)); + // The cursor-report size probe (tty_columns_lines: Save + Goto(999,999) + + // \x1B[6n) is unreliable on the fbcond console. console_draw does not clamp + // Goto beyond the real screen bounds, so the \x1B[6n reply can report the + // *current* cursor position mid boot-text (observed: 15x56) instead of the + // actual dimensions. A bogus tiny width makes the login shell wrap every + // line oddly. Keep the probe result only when it is plausible; otherwise + // fall back to the safe 80x30 default, which mis-wraps on no real + // framebuffer. (A correct size needs fbcond/console_draw to answer the + // probe properly — tracked separately.) + let (columns, lines) = match tty_columns_lines(tty) { + Ok((c, l)) + if (MIN_PLAUSIBLE_COLS..=MAX_PLAUSIBLE_COLS).contains(&c) + && (MIN_PLAUSIBLE_LINES..=MAX_PLAUSIBLE_LINES).contains(&l) => + { + (c, l) + } + _ => (DEFAULT_COLS, DEFAULT_LINES), + }; let tty_fd = tty.as_raw_fd(); let (master_fd, pty) = getpty(columns, lines);