fix: guard ioctl results with when to avoid partial values

ignore-errors + ioctl can return (values 80 nil) when the fd exists
but isn't a terminal. or propagates partial values, causing nil in
w or h. Wrap with multiple-value-bind + when to filter.
This commit is contained in:
2026-05-14 13:07:55 -04:00
parent 4a86ae3274
commit db07f8c3a7
2 changed files with 16 additions and 6 deletions

View File

@@ -175,10 +175,15 @@ as a fallback when a keyword is not in *named-colors*.")
(sb-alien:deref winsize 0))) ;; rows (sb-alien:deref winsize 0))) ;; rows
(sb-alien:free-alien winsize))))) (sb-alien:free-alien winsize)))))
(or ;; Try ioctl on fd 0 first (stdin — stty uses this) (or ;; Try ioctl on fd 0 first (stdin — stty uses this)
(ignore-errors (ioctl-size 0)) (multiple-value-bind (cols rows) (ignore-errors (ioctl-size 0))
(when (and cols rows (> cols 0) (> rows 0))
(values cols rows)))
;; Then try the output stream's fd ;; Then try the output stream's fd
(multiple-value-bind (cols rows)
(ignore-errors (ignore-errors
(ioctl-size (sb-sys:fd-stream-fd (backend-output-stream b)))) (ioctl-size (sb-sys:fd-stream-fd (backend-output-stream b))))
(when (and cols rows (> cols 0) (> rows 0))
(values cols rows)))
;; $COLUMNS/$LINES fallback — set by every POSIX shell ;; $COLUMNS/$LINES fallback — set by every POSIX shell
(ignore-errors (ignore-errors
(let* ((cstr (sb-ext:posix-getenv "COLUMNS")) (let* ((cstr (sb-ext:posix-getenv "COLUMNS"))

View File

@@ -37,9 +37,14 @@
(values (sb-alien:deref winsize 1) (values (sb-alien:deref winsize 1)
(sb-alien:deref winsize 0))) (sb-alien:deref winsize 0)))
(sb-alien:free-alien winsize))))) (sb-alien:free-alien winsize)))))
(or (ignore-errors (ioctl-size 0)) (or (multiple-value-bind (cols rows) (ignore-errors (ioctl-size 0))
(when (and cols rows (> cols 0) (> rows 0))
(values cols rows)))
(multiple-value-bind (cols rows)
(ignore-errors (ignore-errors
(ioctl-size (sb-sys:fd-stream-fd (backend-output-stream b)))) (ioctl-size (sb-sys:fd-stream-fd (backend-output-stream b))))
(when (and cols rows (> cols 0) (> rows 0))
(values cols rows)))
(ignore-errors (ignore-errors
(let* ((cstr (sb-ext:posix-getenv "COLUMNS")) (let* ((cstr (sb-ext:posix-getenv "COLUMNS"))
(rstr (sb-ext:posix-getenv "LINES")) (rstr (sb-ext:posix-getenv "LINES"))