fix: replace stty/tput fallback with direct ioctl on /dev/tty
uiop:run-program can inherit different terminal state than the interactive shell. Opening /dev/tty directly and calling ioctl on that fd is equivalent to what the shell's stty does, and works regardless of SBCL's fd inheritance quirks.
This commit is contained in:
@@ -173,32 +173,21 @@ as a fallback when a keyword is not in *named-colors*.")
|
||||
(values (sb-alien:deref winsize 1) ;; cols
|
||||
(sb-alien:deref winsize 0))) ;; rows
|
||||
(sb-alien:free-alien winsize))))
|
||||
;; stty size — reliable across all shells and terminals.
|
||||
;; SBCL strips COLUMNS/LINES from the environment, so env var
|
||||
;; fallbacks won't work for those names.
|
||||
;; Direct ioctl on /dev/tty — opens the real controlling terminal,
|
||||
;; bypassing any fd weirdness from SBCL's subprocess or stream setup.
|
||||
(ignore-errors
|
||||
(let* ((out (uiop:run-program '("stty" "size")
|
||||
:output :string
|
||||
:ignore-error-status t))
|
||||
(parts (and out (uiop:split-string
|
||||
(string-trim '(#\newline #\space) out)))))
|
||||
(when (and parts (= (length parts) 2))
|
||||
(let ((rows (parse-integer (first parts) :junk-allowed t))
|
||||
(cols (parse-integer (second parts) :junk-allowed t)))
|
||||
(when (and rows cols (> rows 0) (> cols 0))
|
||||
(values cols rows))))))
|
||||
;; tput — final shell fallback for esoteric terminals
|
||||
(ignore-errors
|
||||
(let* ((out (uiop:run-program '("sh" "-c" "tput cols 2>/dev/null; tput lines 2>/dev/null")
|
||||
:output :string
|
||||
:ignore-error-status t))
|
||||
(parts (and out (uiop:split-string
|
||||
(string-trim '(#\newline #\space) out)))))
|
||||
(when (and parts (= (length parts) 2))
|
||||
(let ((cols (parse-integer (first parts) :junk-allowed t))
|
||||
(rows (parse-integer (second parts) :junk-allowed t)))
|
||||
(when (and rows cols (> rows 0) (> cols 0))
|
||||
(values cols rows))))))
|
||||
(let ((tty-fd (sb-unix:unix-open "/dev/tty" sb-unix:o-rdwr 0)))
|
||||
(when tty-fd
|
||||
(unwind-protect
|
||||
(let* ((winsize (sb-alien:make-alien sb-alien:unsigned-short 4)))
|
||||
(sb-unix:unix-ioctl tty-fd 21523 (sb-alien:alien-sap winsize))
|
||||
(let ((cols (sb-alien:deref winsize 1))
|
||||
(rows (sb-alien:deref winsize 0)))
|
||||
(sb-alien:free-alien winsize)
|
||||
(when (and (integerp cols) (integerp rows)
|
||||
(> cols 0) (> rows 0))
|
||||
(values cols rows))))
|
||||
(sb-unix:unix-close tty-fd)))))
|
||||
(values 80 24)))
|
||||
|
||||
(defmethod backend-write ((b modern-backend) string)
|
||||
|
||||
Reference in New Issue
Block a user