debug-repl: fix FFI on Termux/Bionic and Linux libc
ober
43df30bad1150a029ec5ace4cae8878079c4cba0
--- a/src/jcode/core/debug-repl.ss +++ b/src/jcode/core/debug-repl.ss @@ -43,26 +43,37 @@ (def c-dup (foreign-procedure "dup" (int) int)) (def c-errno-location - (let ((mt (symbol->string (machine-type)))) - (if (and (>= (string-length mt) 3) - (string=? (substring mt (- (string-length mt) 3) (string-length mt)) "osx")) - (foreign-procedure "__error" () void*) - (foreign-procedure "__errno_location" () void*)))) + ;; macOS: __error, glibc: __errno_location, Bionic (Android/Termux): __errno. + ;; Try each in turn; bind to the first one that resolves. + (let ((names '("__error" "__errno_location" "__errno"))) + (let loop ((ns names)) + (cond + ((null? ns) + (lambda () 0)) ;; fallback — get-errno will return 0 + (#t + (let ((proc (guard (e [#t #f]) + (foreign-procedure (car ns) () void*)))) + (if proc proc (loop (cdr ns))))))))) (def (get-errno) (foreign-ref 'int (c-errno-location) 0)) ;; ---- Constants ---- +(def *is-osx?* + (let ((mt (symbol->string (machine-type)))) + (and (>= (string-length mt) 3) + (string=? (substring mt (- (string-length mt) 3) (string-length mt)) "osx")))) + (def AF_INET 2) (def SOCK_STREAM 1) -(def SOL_SOCKET #xffff) ;; macOS/FreeBSD; Linux would be 1 -(def SO_REUSEADDR 4) ;; macOS/FreeBSD; Linux would be 2 +(def SOL_SOCKET (if *is-osx?* #xffff 1)) +(def SO_REUSEADDR (if *is-osx?* 4 2)) (def SOCKADDR_IN_SIZE 16) (def F_GETFL 3) (def F_SETFL 4) -(def O_NONBLOCK #x4) ;; macOS; Linux would be #x800 +(def O_NONBLOCK (if *is-osx?* #x4 #x800)) (def EINTR 4) -(def EAGAIN 35) ;; macOS; Linux would be 11 +(def EAGAIN (if *is-osx?* 35 11)) (def *retry-delay* (make-time 'time-duration 10000000 0)) ;; 10ms ;; ---- Helpers ---- @@ -78,9 +89,14 @@ (when (< i SOCKADDR_IN_SIZE) (foreign-set! 'unsigned-8 buf i 0) (lp (+ i 1)))) - ;; macOS sockaddr_in: sin_len(1) + sin_family(1) + sin_port(2) + sin_addr(4) - (foreign-set! 'unsigned-8 buf 0 SOCKADDR_IN_SIZE) ;; sin_len - (foreign-set! 'unsigned-8 buf 1 AF_INET) ;; sin_family + ;; macOS/BSD sockaddr_in: sin_len(1) + sin_family(1) + sin_port(2) + sin_addr(4) + ;; Linux/Android sockaddr_in: sin_family(2) + sin_port(2) + sin_addr(4) + (cond + (*is-osx?* + (foreign-set! 'unsigned-8 buf 0 SOCKADDR_IN_SIZE) ;; sin_len + (foreign-set! 'unsigned-8 buf 1 AF_INET)) ;; sin_family + (#t + (foreign-set! 'unsigned-short buf 0 AF_INET))) ;; sin_family (16-bit) (foreign-set! 'unsigned-short buf 2 (c-htons port)) ;; 127.0.0.1 = bytes 127, 0, 0, 1 at offset 4 (foreign-set! 'unsigned-8 buf 4 127)