diff --git a/src/backend/modern.lisp b/src/backend/modern.lisp index e53a2d8..d87bc28 100644 --- a/src/backend/modern.lisp +++ b/src/backend/modern.lisp @@ -164,27 +164,30 @@ as a fallback when a keyword is not in *named-colors*.") (values)) (defmethod backend-size ((b modern-backend)) - (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))) + (flet ((ioctl-size (fd) + (let* ((+tiocgwinsz+ 21523) ; 0x5413 on Linux + (winsize (sb-alien:make-alien sb-alien:unsigned-short 4))) + (unwind-protect + (progn + (sb-unix:unix-ioctl fd +tiocgwinsz+ + (sb-alien:alien-sap winsize)) + (values (sb-alien:deref winsize 1) ;; cols + (sb-alien:deref winsize 0))) ;; rows + (sb-alien:free-alien winsize))))) + (or ;; Try ioctl on fd 0 first (stdin — stty uses this) + (ignore-errors (ioctl-size 0)) + ;; Then try the output stream's fd + (ignore-errors + (ioctl-size (sb-sys:fd-stream-fd (backend-output-stream b)))) + ;; $COLUMNS/$LINES fallback — set by every POSIX shell + (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))) diff --git a/src/backend/simple.lisp b/src/backend/simple.lisp index b0fb84a..b01ffce 100644 --- a/src/backend/simple.lisp +++ b/src/backend/simple.lisp @@ -27,27 +27,27 @@ (values)) (defmethod backend-size ((b simple-backend)) - (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))) + (flet ((ioctl-size (fd) + (let* ((+tiocgwinsz+ 21523) + (winsize (sb-alien:make-alien sb-alien:unsigned-short 4))) + (unwind-protect + (progn + (sb-unix:unix-ioctl fd +tiocgwinsz+ + (sb-alien:alien-sap winsize)) + (values (sb-alien:deref winsize 1) + (sb-alien:deref winsize 0))) + (sb-alien:free-alien winsize))))) + (or (ignore-errors (ioctl-size 0)) + (ignore-errors + (ioctl-size (sb-sys:fd-stream-fd (backend-output-stream b)))) + (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)))