切换至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
相关产品推荐
相关产品推荐

