fix: use :input :inherit for stty size subprocess
:input :inherit preserves the parent's fd 0 (the terminal) in the child process, so stty can query it via ioctl. Previous approaches (:input :interactive, /dev/tty) all failed because uiop's process setup redirects stdin away from the terminal.
This commit is contained in:
@@ -162,21 +162,20 @@ as a fallback when a keyword is not in *named-colors*.")
|
||||
(values))
|
||||
|
||||
(defmethod backend-size ((b modern-backend))
|
||||
(or ;; tput lines / tput cols via subprocess — most reliable across
|
||||
;; all systems. Each outputs a single number. Works in any
|
||||
;; subprocess context, no parsing complexity.
|
||||
(or ;; stty size with :input :inherit — preserves the parent's fd 0
|
||||
;; (the terminal) so stty can query it via ioctl.
|
||||
(multiple-value-bind (cols rows)
|
||||
(values
|
||||
(ignore-errors
|
||||
(parse-integer
|
||||
(string-trim '(#\newline #\space)
|
||||
(uiop:run-program '("tput" "cols") :output :string
|
||||
:ignore-error-status t))))
|
||||
(ignore-errors
|
||||
(parse-integer
|
||||
(string-trim '(#\newline #\space)
|
||||
(uiop:run-program '("tput" "lines") :output :string
|
||||
:ignore-error-status t)))))
|
||||
(let* ((out (uiop:run-program '("stty" "size") :output :string
|
||||
:input :inherit
|
||||
:ignore-error-status t))
|
||||
(parts (and out (uiop:split-string
|
||||
(string-trim '(#\newline #\space) out)))))
|
||||
(when (and parts (= (length parts) 2))
|
||||
(let ((r (parse-integer (first parts) :junk-allowed t))
|
||||
(c (parse-integer (second parts) :junk-allowed t)))
|
||||
(when (and r c (> r 0) (> c 0))
|
||||
(values c r))))))
|
||||
(when (and cols rows (> cols 0) (> rows 0))
|
||||
(values cols rows)))
|
||||
;; ioctl on stdout fd — fast, correct after SIGWINCH at runtime.
|
||||
|
||||
@@ -22,19 +22,19 @@
|
||||
(values))
|
||||
|
||||
(defmethod backend-size ((b simple-backend))
|
||||
(or ;; tput cols / tput lines via subprocess
|
||||
(or ;; stty size with :input :inherit — preserves parent's fd 0.
|
||||
(multiple-value-bind (cols rows)
|
||||
(values
|
||||
(ignore-errors
|
||||
(parse-integer
|
||||
(string-trim '(#\newline #\space)
|
||||
(uiop:run-program '("tput" "cols") :output :string
|
||||
:ignore-error-status t))))
|
||||
(ignore-errors
|
||||
(parse-integer
|
||||
(string-trim '(#\newline #\space)
|
||||
(uiop:run-program '("tput" "lines") :output :string
|
||||
:ignore-error-status t)))))
|
||||
(let* ((out (uiop:run-program '("stty" "size") :output :string
|
||||
:input :inherit
|
||||
:ignore-error-status t))
|
||||
(parts (and out (uiop:split-string
|
||||
(string-trim '(#\newline #\space) out)))))
|
||||
(when (and parts (= (length parts) 2))
|
||||
(let ((r (parse-integer (first parts) :junk-allowed t))
|
||||
(c (parse-integer (second parts) :junk-allowed t)))
|
||||
(when (and r c (> r 0) (> c 0))
|
||||
(values c r))))))
|
||||
(when (and cols rows (> cols 0) (> rows 0))
|
||||
(values cols rows)))
|
||||
;; ioctl on stdout fd — fast, correct after SIGWINCH at runtime.
|
||||
|
||||
Reference in New Issue
Block a user