fix: use ioctl on fd 0 (stdin) as primary sizing method
The parent's fd 0 IS the real terminal when running from a shell. This directly queries the terminal size without subprocess or alien complexity. Added proper when guard on the unix-ioctl result.
This commit is contained in:
@@ -162,20 +162,20 @@ as a fallback when a keyword is not in *named-colors*.")
|
|||||||
(values))
|
(values))
|
||||||
|
|
||||||
(defmethod backend-size ((b modern-backend))
|
(defmethod backend-size ((b modern-backend))
|
||||||
(or ;; stty size with :input :interactive — opens /dev/tty for the
|
(or ;; ioctl on fd 0 (stdin) — the parent's own terminal, which IS
|
||||||
;; child's stdin so stty can query the terminal via ioctl.
|
;; the real controlling terminal when running from a shell.
|
||||||
(multiple-value-bind (cols rows)
|
(multiple-value-bind (cols rows)
|
||||||
(ignore-errors
|
(ignore-errors
|
||||||
(let* ((out (uiop:run-program '("stty" "size") :output :string
|
(let ((winsize (sb-alien:make-alien sb-alien:unsigned-short 4)))
|
||||||
:input :interactive
|
(unwind-protect
|
||||||
:ignore-error-status t))
|
(let ((ok (sb-unix:unix-ioctl 0 21523
|
||||||
(parts (and out (uiop:split-string
|
(sb-alien:alien-sap winsize))))
|
||||||
(string-trim '(#\newline #\space) out)))))
|
(when ok
|
||||||
(when (and parts (= (length parts) 2))
|
(let ((c (sb-alien:deref winsize 1))
|
||||||
(let ((r (parse-integer (first parts) :junk-allowed t))
|
(r (sb-alien:deref winsize 0)))
|
||||||
(c (parse-integer (second parts) :junk-allowed t)))
|
(when (and c r (> c 0) (> r 0))
|
||||||
(when (and r c (> r 0) (> c 0))
|
(values c r)))))
|
||||||
(values c r))))))
|
(sb-alien:free-alien winsize))))
|
||||||
(when (and cols rows (> cols 0) (> rows 0))
|
(when (and cols rows (> cols 0) (> rows 0))
|
||||||
(values cols rows)))
|
(values cols rows)))
|
||||||
;; ioctl on stdout fd — fast, correct after SIGWINCH at runtime.
|
;; ioctl on stdout fd — fast, correct after SIGWINCH at runtime.
|
||||||
|
|||||||
@@ -22,19 +22,19 @@
|
|||||||
(values))
|
(values))
|
||||||
|
|
||||||
(defmethod backend-size ((b simple-backend))
|
(defmethod backend-size ((b simple-backend))
|
||||||
(or ;; stty size with :input :interactive — opens /dev/tty.
|
(or ;; ioctl on fd 0 (stdin) — the parent's own terminal.
|
||||||
(multiple-value-bind (cols rows)
|
(multiple-value-bind (cols rows)
|
||||||
(ignore-errors
|
(ignore-errors
|
||||||
(let* ((out (uiop:run-program '("stty" "size") :output :string
|
(let ((winsize (sb-alien:make-alien sb-alien:unsigned-short 4)))
|
||||||
:input :interactive
|
(unwind-protect
|
||||||
:ignore-error-status t))
|
(let ((ok (sb-unix:unix-ioctl 0 21523
|
||||||
(parts (and out (uiop:split-string
|
(sb-alien:alien-sap winsize))))
|
||||||
(string-trim '(#\newline #\space) out)))))
|
(when ok
|
||||||
(when (and parts (= (length parts) 2))
|
(let ((c (sb-alien:deref winsize 1))
|
||||||
(let ((r (parse-integer (first parts) :junk-allowed t))
|
(r (sb-alien:deref winsize 0)))
|
||||||
(c (parse-integer (second parts) :junk-allowed t)))
|
(when (and c r (> c 0) (> r 0))
|
||||||
(when (and r c (> r 0) (> c 0))
|
(values c r)))))
|
||||||
(values c r))))))
|
(sb-alien:free-alien winsize))))
|
||||||
(when (and cols rows (> cols 0) (> rows 0))
|
(when (and cols rows (> cols 0) (> rows 0))
|
||||||
(values cols rows)))
|
(values cols rows)))
|
||||||
;; ioctl on stdout fd — fast, correct after SIGWINCH at runtime.
|
;; ioctl on stdout fd — fast, correct after SIGWINCH at runtime.
|
||||||
|
|||||||
Reference in New Issue
Block a user