You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

切换至Apple Silicon后Chez Scheme FFI终端窗口大小获取函数失效

Chez Scheme FFI获取终端窗口大小在Apple Silicon上失效

原代码用于获取终端模拟器的行列数,在x86架构的Chez Scheme 9.5.8中可正常工作。切换到Apple Silicon开发机器后,使用Chez Scheme 9.9.9-pre-release-20版本时,代码能正常加载运行且无报错,但无论终端窗口实际大小如何,始终返回(0 0)。版本控制仓库显示代码无变更,目前无法访问Intel机器确认是否存在环境相关的代码适配问题。

查阅Chez Scheme 9.9.9的发布说明,其中FFI相关变更未提及会导致此问题,但显然存在未被注意的细节。

相关代码如下:

;;; win-size-demo.ss -- Procedure to return the size (in rows and columns)
;;; of the terminal it is running in.
(import (chezscheme))

;; Load the C runtime library. Only tested on macOS. The other clauses
;; were taken from examples in other files of the Chez Scheme
;; source distribution.
(case (machine-type)
  [(i3le ti3le a6le ta6le) (load-shared-object "libc.so.6")]
  [(i3osx ti3osx a6osx ta6osx) (load-shared-object "libc.dylib")]
  [(i3nt ti3nt a6nt ta6nt) (begin (load-shared-object "msvcrt.dll")
                                  (load-shared-object "kernel32.dll"))]
  ;; The following is a new addition for Apple Silicon systems.
  [(arm64osx tarm64osx) (load-shared-object "libSystem.dylib")]
  [else (load-shared-object "libc.so")])

;; The preferred way to interrogate the window size is through the
;; `ioctl` function from the underlying C implementation. Here's
;; how that (used to) works.

;; Define some file descriptors for stdin/out. Couldn't find this
;; documented anywhere. These values are from Chez expediter.c.
(define STDIN_FD 0)
(define STDOUT_FD 1)

;; Value from /Library/Developer/CommandLineTools/SDKs/MacOSX13.3.sdk/usr/includes/sys/ttycom.h.
;; This value is caclulated via a C macro in <sys/ioccom.h>.
(define TIOCGWINSZ #x40087468)

;; From <sys/ttycom.h>.
(define-ftype win-size
  (struct
    [ws-row unsigned-short] ; number of rows in the window, in characters
    [ws-col unsigned-short] ; number of columns in the window, in characters
    [ws-xpixel unsigned-short] ; horizontal size of the window, in pixels
    [ws-ypixel unsigned-short] ; vertical size of the window, in pixels
    ))

(define ioctl (foreign-procedure "ioctl" (int int (* win-size)) int))

(define errno (foreign-procedure "(cs)s_errno" () int))
(define strerror (foreign-procedure "(cs)s_strerror" (int) scheme-object))

;; Return the size of the terminal window using the `ioctl` function
;; from the underlying C library.
(define (window-size)
  (let* ((win-size-buf (foreign-alloc (ftype-sizeof win-size)))
         (win-size-ptr (make-ftype-pointer win-size win-size-buf)))
    (let ((the-size (dynamic-wind
                      (lambda () #f)
                      (lambda () (let ((ctl-result (ioctl STDIN_FD TIOCGWINSZ win-size-ptr)))
                                   (if (negative? ctl-result)
                                       (let ((cep (current-error-port)))
                                         (display "Error getting display size.\n" cep)
                                         (display (strerror (errno)) cep)
                                         (newline cep)
                                         (list -1 -1))
                                       (list (ftype-ref win-size (ws-row) win-size-ptr)
                                             (ftype-ref win-size (ws-col) win-size-ptr)))))
                      (lambda () (foreign-free win-size-buf))))
      the-size)))

内容的提问来源于stack exchange,提问作者clartaq

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 16:59:51