diff --git a/src/backend/modern.lisp b/src/backend/modern.lisp index 8766227..4362763 100644 --- a/src/backend/modern.lisp +++ b/src/backend/modern.lisp @@ -162,20 +162,20 @@ as a fallback when a keyword is not in *named-colors*.") (values)) (defmethod backend-size ((b modern-backend)) - (or ;; stty size with :input :interactive — opens /dev/tty for the - ;; child's stdin so stty can query the terminal via ioctl. + (or ;; ioctl on fd 0 (stdin) — the parent's own terminal, which IS + ;; the real controlling terminal when running from a shell. (multiple-value-bind (cols rows) (ignore-errors - (let* ((out (uiop:run-program '("stty" "size") :output :string - :input :interactive - :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)))))) + (let ((winsize (sb-alien:make-alien sb-alien:unsigned-short 4))) + (unwind-protect + (let ((ok (sb-unix:unix-ioctl 0 21523 + (sb-alien:alien-sap winsize)))) + (when ok + (let ((c (sb-alien:deref winsize 1)) + (r (sb-alien:deref winsize 0))) + (when (and c r (> c 0) (> r 0)) + (values c r))))) + (sb-alien:free-alien winsize)))) (when (and cols rows (> cols 0) (> rows 0)) (values cols rows))) ;; ioctl on stdout fd — fast, correct after SIGWINCH at runtime. diff --git a/src/backend/simple.lisp b/src/backend/simple.lisp index 33529a3..2fbfdb3 100644 --- a/src/backend/simple.lisp +++ b/src/backend/simple.lisp @@ -22,19 +22,19 @@ (values)) (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) (ignore-errors - (let* ((out (uiop:run-program '("stty" "size") :output :string - :input :interactive - :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)))))) + (let ((winsize (sb-alien:make-alien sb-alien:unsigned-short 4))) + (unwind-protect + (let ((ok (sb-unix:unix-ioctl 0 21523 + (sb-alien:alien-sap winsize)))) + (when ok + (let ((c (sb-alien:deref winsize 1)) + (r (sb-alien:deref winsize 0))) + (when (and c r (> c 0) (> r 0)) + (values c r))))) + (sb-alien:free-alien winsize)))) (when (and cols rows (> cols 0) (> rows 0)) (values cols rows))) ;; ioctl on stdout fd — fast, correct after SIGWINCH at runtime.