fix: revert to simple ioctl-first with env var fallback
The previous logic (check ioctl result, prefer env when 80x24) added complexity and crashes. Simple or with env vars after ioctl is safe: ioctl returns 80x24 on stdout fd mismatch, env vars (COLUMNS/LINES from shell) provide the correct initial size.
This commit is contained in:
@@ -164,43 +164,27 @@ as a fallback when a keyword is not in *named-colors*.")
|
||||
(values))
|
||||
|
||||
(defmethod backend-size ((b modern-backend))
|
||||
(multiple-value-bind (w h)
|
||||
(or (ignore-errors
|
||||
(let* ((+tiocgwinsz+ 21523) ; 0x5413 on Linux
|
||||
(winsize (sb-alien:make-alien sb-alien:unsigned-short 4)))
|
||||
(unwind-protect
|
||||
(progn
|
||||
(sb-unix:unix-ioctl (sb-sys:fd-stream-fd (backend-output-stream b))
|
||||
+tiocgwinsz+
|
||||
(sb-alien:alien-sap winsize))
|
||||
(values (sb-alien:deref winsize 1) ;; cols
|
||||
(sb-alien:deref winsize 0))) ;; rows
|
||||
(sb-alien:free-alien winsize))))
|
||||
(values 0 0))
|
||||
;; If ioctl returned a plausible size (not the 80x24 default),
|
||||
;; trust it — it will be correct at runtime after SIGWINCH.
|
||||
(if (and (> w 80) (> h 24))
|
||||
(values w h)
|
||||
;; ioctl returned 80x24 or less — suspicious. Try $COLUMNS/
|
||||
;; $LINES from the shell, which reflect the true size at
|
||||
;; process start even when ioctl on stdout's fd disagrees.
|
||||
(or (ignore-errors
|
||||
(let* ((cstr (sb-ext:posix-getenv "COLUMNS"))
|
||||
(rstr (sb-ext:posix-getenv "LINES"))
|
||||
(cols (when cstr (parse-integer cstr :junk-allowed t)))
|
||||
(rows (when rstr (parse-integer rstr :junk-allowed t))))
|
||||
;; Some environments set only COLUMNS or only LINES.
|
||||
;; If one is missing, try the other from stty.
|
||||
(when (and cols (null rows))
|
||||
(let* ((out (uiop:run-program '("stty" "size")
|
||||
:output :string
|
||||
:ignore-error-status t))
|
||||
(parts (when out (uiop:split-string (string-trim '(#\newline #\space) out)))))
|
||||
(setf rows (when (and parts (= (length parts) 2))
|
||||
(parse-integer (second parts) :junk-allowed t)))))
|
||||
(when (and cols rows (> cols 0) (> rows 0))
|
||||
(values cols rows))))
|
||||
(values w h)))))
|
||||
(or (ignore-errors
|
||||
(let* ((+tiocgwinsz+ 21523) ; 0x5413 on Linux
|
||||
(winsize (sb-alien:make-alien sb-alien:unsigned-short 4)))
|
||||
(unwind-protect
|
||||
(progn
|
||||
(sb-unix:unix-ioctl (sb-sys:fd-stream-fd (backend-output-stream b))
|
||||
+tiocgwinsz+
|
||||
(sb-alien:alien-sap winsize))
|
||||
(values (sb-alien:deref winsize 1) ;; cols
|
||||
(sb-alien:deref winsize 0))) ;; rows
|
||||
(sb-alien:free-alien winsize))))
|
||||
;; $COLUMNS/$LINES fallback — some systems don't update the
|
||||
;; TTY size via ioctl on stdout's fd.
|
||||
(ignore-errors
|
||||
(let* ((cstr (sb-ext:posix-getenv "COLUMNS"))
|
||||
(rstr (sb-ext:posix-getenv "LINES"))
|
||||
(cols (when cstr (parse-integer cstr :junk-allowed t)))
|
||||
(rows (when rstr (parse-integer rstr :junk-allowed t))))
|
||||
(when (and cols rows (> cols 0) (> rows 0))
|
||||
(values cols rows))))
|
||||
(values 80 24)))
|
||||
|
||||
(defmethod backend-write ((b modern-backend) string)
|
||||
(let ((stream (backend-output-stream b)))
|
||||
|
||||
@@ -27,37 +27,27 @@
|
||||
(values))
|
||||
|
||||
(defmethod backend-size ((b simple-backend))
|
||||
(multiple-value-bind (w h)
|
||||
(or (ignore-errors
|
||||
(let* ((+tiocgwinsz+ 21523)
|
||||
(winsize (sb-alien:make-alien sb-alien:unsigned-short 4)))
|
||||
(unwind-protect
|
||||
(progn
|
||||
(sb-unix:unix-ioctl (sb-sys:fd-stream-fd
|
||||
(backend-output-stream b))
|
||||
+tiocgwinsz+
|
||||
(sb-alien:alien-sap winsize))
|
||||
(values (sb-alien:deref winsize 1)
|
||||
(sb-alien:deref winsize 0)))
|
||||
(sb-alien:free-alien winsize))))
|
||||
(values 0 0))
|
||||
(if (and (> w 80) (> h 24))
|
||||
(values w h)
|
||||
(or (ignore-errors
|
||||
(let* ((cstr (sb-ext:posix-getenv "COLUMNS"))
|
||||
(rstr (sb-ext:posix-getenv "LINES"))
|
||||
(cols (when cstr (parse-integer cstr :junk-allowed t)))
|
||||
(rows (when rstr (parse-integer rstr :junk-allowed t))))
|
||||
(when (and cols (null rows))
|
||||
(let* ((out (uiop:run-program '("stty" "size")
|
||||
:output :string
|
||||
:ignore-error-status t))
|
||||
(parts (when out (uiop:split-string (string-trim '(#\newline #\space) out)))))
|
||||
(setf rows (when (and parts (= (length parts) 2))
|
||||
(parse-integer (second parts) :junk-allowed t)))))
|
||||
(when (and cols rows (> cols 0) (> rows 0))
|
||||
(values cols rows))))
|
||||
(values w h)))))
|
||||
(or (ignore-errors
|
||||
(let* ((+tiocgwinsz+ 21523)
|
||||
(winsize (sb-alien:make-alien sb-alien:unsigned-short 4)))
|
||||
(unwind-protect
|
||||
(progn
|
||||
(sb-unix:unix-ioctl (sb-sys:fd-stream-fd
|
||||
(backend-output-stream b))
|
||||
+tiocgwinsz+
|
||||
(sb-alien:alien-sap winsize))
|
||||
(values (sb-alien:deref winsize 1)
|
||||
(sb-alien:deref winsize 0)))
|
||||
(sb-alien:free-alien winsize))))
|
||||
;; $COLUMNS/$LINES fallback
|
||||
(ignore-errors
|
||||
(let* ((cstr (sb-ext:posix-getenv "COLUMNS"))
|
||||
(rstr (sb-ext:posix-getenv "LINES"))
|
||||
(cols (when cstr (parse-integer cstr :junk-allowed t)))
|
||||
(rows (when rstr (parse-integer rstr :junk-allowed t))))
|
||||
(when (and cols rows (> cols 0) (> rows 0))
|
||||
(values cols rows))))
|
||||
(values 80 24)))
|
||||
|
||||
(defmethod backend-write ((b simple-backend) string)
|
||||
(let ((stream (backend-output-stream b)))
|
||||
|
||||
Reference in New Issue
Block a user