Fix FreeBSD platform constants: O_* flags, struct stat, sockaddr_in, signals
ober
8c8c0ba4c2534ffc4bcd7bc2e7163f9f7ea37e5e
--- a/lib/std/net/repl.sls +++ b/lib/std/net/repl.sls @@ -36,17 +36,18 @@ (foreign-procedure "__errno_location" () void*))) (define (get-errno) (foreign-ref 'int (c-errno-location) 0)) - ;; Constants + ;; Constants (values differ between Linux and FreeBSD) + (define *freebsd?* (memq (machine-type) '(a6fb ta6fb i3fb ti3fb arm64fb))) (define AF_INET 2) (define SOCK_STREAM 1) - (define SOL_SOCKET 1) - (define SO_REUSEADDR 2) + (define SOL_SOCKET (if *freebsd?* #xffff 1)) + (define SO_REUSEADDR (if *freebsd?* 4 2)) (define SOCKADDR_IN_SIZE 16) (define F_GETFL 3) (define F_SETFL 4) - (define O_NONBLOCK #x800) + (define O_NONBLOCK (if *freebsd?* #x4 #x800)) (define EINTR 4) - (define EAGAIN 11) + (define EAGAIN (if *freebsd?* 35 11)) (define *retry-delay* (make-time 'time-duration 10000000 0)) ;; ========== Helpers ========== @@ -62,7 +63,11 @@ (when (< i SOCKADDR_IN_SIZE) (foreign-set! 'unsigned-8 buf i 0) (lp (+ i 1)))) - (foreign-set! 'unsigned-short buf 0 AF_INET) + (if *freebsd?* + (begin + (foreign-set! 'unsigned-8 buf 0 SOCKADDR_IN_SIZE) ;; sin_len + (foreign-set! 'unsigned-8 buf 1 AF_INET)) ;; sin_family (uint8) + (foreign-set! 'unsigned-short buf 0 AF_INET)) ;; sin_family (uint16) (foreign-set! 'unsigned-short buf 2 (c-htons port)) ;; sin_addr stays 0 = INADDR_ANY buf)) --- a/lib/std/net/tcp-raw.sls +++ b/lib/std/net/tcp-raw.sls @@ -43,13 +43,14 @@ (define (get-errno) (foreign-ref 'int (c-errno-location) 0)) (define EINTR 4) - ;; Constants + ;; Constants (values differ between Linux and FreeBSD) + (define *freebsd?* (memq (machine-type) '(a6fb ta6fb i3fb ti3fb arm64fb))) (define AF_INET 2) (define SOCK_STREAM 1) - (define SOL_SOCKET 1) - (define SO_REUSEADDR 2) - (define SO_RCVTIMEO 20) - (define SO_SNDTIMEO 21) + (define SOL_SOCKET (if *freebsd?* #xffff 1)) + (define SO_REUSEADDR (if *freebsd?* 4 2)) + (define SO_RCVTIMEO (if *freebsd?* #x1006 20)) + (define SO_SNDTIMEO (if *freebsd?* #x1005 21)) (define SOCKADDR_IN_SIZE 16) ;; ========== sockaddr_in ========== @@ -60,7 +61,11 @@ (when (< i SOCKADDR_IN_SIZE) (foreign-set! 'unsigned-8 buf i 0) (lp (+ i 1)))) - (foreign-set! 'unsigned-short buf 0 AF_INET) + (if *freebsd?* + (begin + (foreign-set! 'unsigned-8 buf 0 SOCKADDR_IN_SIZE) ;; sin_len + (foreign-set! 'unsigned-8 buf 1 AF_INET)) ;; sin_family (uint8) + (foreign-set! 'unsigned-short buf 0 AF_INET)) ;; sin_family (uint16) (foreign-set! 'unsigned-short buf 2 (c-htons port)) (let ([addr-ptr (+ buf 4)]) (when (= (c-inet-pton AF_INET address addr-ptr) 0) --- a/lib/std/net/tcp.sls +++ b/lib/std/net/tcp.sls @@ -56,18 +56,20 @@ (foreign-procedure "__errno_location" () void*))) (define (get-errno) (foreign-ref 'int (c-errno-location) 0)) (define EINTR 4) - (define EAGAIN 11) + (define *freebsd?* (memq (machine-type) '(a6fb ta6fb i3fb ti3fb arm64fb))) + (define EAGAIN (if *freebsd?* 35 11)) ;; fcntl constants (define F_GETFL 3) (define F_SETFL 4) - (define O_NONBLOCK #x800) + (define O_NONBLOCK + (if (memq (machine-type) '(a6fb ta6fb i3fb ti3fb arm64fb)) #x4 #x800)) ;; Constants (define AF_INET 2) (define SOCK_STREAM 1) - (define SOL_SOCKET 1) - (define SO_REUSEADDR 2) + (define SOL_SOCKET (if *freebsd?* #xffff 1)) + (define SO_REUSEADDR (if *freebsd?* 4 2)) (define SOCKADDR_IN_SIZE 16) ;; sizeof(struct sockaddr_in) on Linux ;; GC-safe retry delay: 10ms via Chez's sleep (not a foreign call). @@ -88,8 +90,14 @@ (when (< i SOCKADDR_IN_SIZE) (foreign-set! 'unsigned-8 buf i 0) (lp (+ i 1)))) - ;; sin_family = AF_INET (offset 0, 2 bytes) - (foreign-set! 'unsigned-short buf 0 AF_INET) + ;; sin_family = AF_INET + ;; FreeBSD sockaddr_in has sin_len (uint8) at offset 0, sin_family (uint8) at offset 1 + ;; Linux sockaddr_in has sin_family (uint16) at offset 0 + (if *freebsd?* + (begin + (foreign-set! 'unsigned-8 buf 0 16) ;; sin_len = sizeof(sockaddr_in) + (foreign-set! 'unsigned-8 buf 1 AF_INET)) ;; sin_family (uint8) + (foreign-set! 'unsigned-short buf 0 AF_INET)) ;; sin_family (uint16) ;; sin_port = htons(port) (offset 2, 2 bytes) (foreign-set! 'unsigned-short buf 2 (c-htons port)) ;; sin_addr (offset 4, 4 bytes) — parse address string --- a/lib/std/odb.sls +++ b/lib/std/odb.sls @@ -184,6 +184,11 @@ ;; Store lifecycle ;; ========================================================================= + ;; Platform detection for open(2) flag constants + (define *freebsd?* (memq (machine-type) '(a6fb ta6fb i3fb ti3fb arm64fb))) + (define %O_CREAT (if *freebsd?* #x200 #x40)) + (define %O_TRUNC (if *freebsd?* #x400 #x200)) + ;; open(2) and ftruncate(2) FFI for creating/growing backing files (define %c-open (foreign-procedure "open" (string int int) int)) @@ -208,7 +213,7 @@ ;; Lock the directory (let* ([lock-path (string-append path "/odb.lock")] [fd (%c-open lock-path - (bitwise-ior #x40 #x2) ;; O_CREAT | O_RDWR + (bitwise-ior %O_CREAT #x2) ;; O_CREAT | O_RDWR #o644)]) (when (< fd 0) (error 'odb-open "cannot create lock file" lock-path)) @@ -407,7 +412,7 @@ (define (create-backing-file! path size) (let ([fd (%c-open path - (bitwise-ior #x42 #x200) ;; O_CREAT | O_RDWR | O_TRUNC + (bitwise-ior (bitwise-ior %O_CREAT #x2) %O_TRUNC) ;; O_CREAT | O_RDWR | O_TRUNC #o644)]) (when (< fd 0) (error 'create-backing-file! "cannot create file" path)) --- a/lib/std/os/fcntl.sls +++ b/lib/std/os/fcntl.sls @@ -42,9 +42,10 @@ (define F_SETFL 4) ;; File status flags (F_GETFL/F_SETFL) - (define O_APPEND #x400) - (define O_NONBLOCK #x800) - (define O_CLOEXEC #x80000) + (define *freebsd?* (memq (machine-type) '(a6fb ta6fb i3fb ti3fb arm64fb))) + (define O_APPEND (if *freebsd?* #x8 #x400)) + (define O_NONBLOCK (if *freebsd?* #x4 #x800)) + (define O_CLOEXEC (if *freebsd?* #x100000 #x80000)) ;; File descriptor flags (F_GETFD/F_SETFD) (define FD_CLOEXEC 1) --- a/lib/std/os/flock.sls +++ b/lib/std/os/flock.sls @@ -28,7 +28,8 @@ (foreign-procedure "__error" () void*) (foreign-procedure "__errno_location" () void*))) (define (get-errno) (foreign-ref 'int (c-errno-location) 0)) - (define EWOULDBLOCK 11) ;; same as EAGAIN on Linux + (define *freebsd?* (memq (machine-type) '(a6fb ta6fb i3fb ti3fb arm64fb))) + (define EWOULDBLOCK (if *freebsd?* 35 11)) ;; ========== Constants ========== --- a/lib/std/os/mmap.sls +++ b/lib/std/os/mmap.sls @@ -38,8 +38,11 @@ (import (chezscheme)) + ;;; ========== Platform detection ========== + (define *freebsd?* (memq (machine-type) '(a6fb ta6fb i3fb ti3fb arm64fb))) + ;;; ========== POSIX constants ========== - ;; Values for Linux x86-64. Adjust for other platforms. + ;; Values for Linux x86-64 and FreeBSD. Platform-specific values use *freebsd?* guard. (define PROT_READ 1) (define PROT_WRITE 2) @@ -48,7 +51,7 @@ (define MAP_SHARED 1) (define MAP_PRIVATE 2) - (define MAP_ANONYMOUS #x20) + (define MAP_ANONYMOUS (if *freebsd?* #x1000 #x20)) (define MAP_FAILED -1) ; mmap returns (void*)-1 on failure (define MADV_SEQUENTIAL 2) @@ -107,8 +110,8 @@ (define O_RDONLY 0) (define O_RDWR 2) - (define O_CREAT #x40) - (define O_TRUNC #x200) + (define O_CREAT (if *freebsd?* #x200 #x40)) + (define O_TRUNC (if *freebsd?* #x400 #x200)) (define SEEK_END 2) ;;; ========== mmap region record ========== --- a/lib/std/os/posix.sls +++ b/lib/std/os/posix.sls @@ -199,16 +199,18 @@ (define (WSTOPSIG s) (bitwise-arithmetic-shift-right (bitwise-and s #xff00) 8)) ;; ========== Open Flags ========== - (define O_RDONLY #o0) - (define O_WRONLY #o1) - (define O_RDWR #o2) - (define O_CREAT #o100) - (define O_EXCL #o200) - (define O_NOCTTY #o400) - (define O_TRUNC #o1000) - (define O_APPEND #o2000) - (define O_NONBLOCK #o4000) - (define O_CLOEXEC #o2000000) + ;; Values differ between Linux and FreeBSD + (define *freebsd?* (memq (machine-type) '(a6fb ta6fb i3fb ti3fb arm64fb))) + (define O_RDONLY #x0) + (define O_WRONLY #x1) + (define O_RDWR #x2) + (define O_CREAT (if *freebsd?* #x200 #x40)) + (define O_EXCL (if *freebsd?* #x800 #x80)) + (define O_NOCTTY (if *freebsd?* #x8000 #x100)) + (define O_TRUNC (if *freebsd?* #x400 #x200)) + (define O_APPEND (if *freebsd?* #x8 #x400)) + (define O_NONBLOCK (if *freebsd?* #x4 #x800)) + (define O_CLOEXEC (if *freebsd?* #x100000 #x80000)) ;; ========== Seek Constants ========== (define SEEK_SET 0) @@ -222,9 +224,11 @@ (define X_OK 1) ;; ========== Signal Mask Constants ========== - (define SIG_BLOCK 0) - (define SIG_UNBLOCK 1) - (define SIG_SETMASK 2) + ;; FreeBSD: SIG_BLOCK=1, SIG_UNBLOCK=2, SIG_SETMASK=3 + ;; Linux: SIG_BLOCK=0, SIG_UNBLOCK=1, SIG_SETMASK=2 + (define SIG_BLOCK (if *freebsd?* 1 0)) + (define SIG_UNBLOCK (if *freebsd?* 2 1)) + (define SIG_SETMASK (if *freebsd?* 3 2)) ;; ========== Terminal Constants ========== (define TCSANOW 0) @@ -361,8 +365,8 @@ (define (posix-kill pid sig) (check-posix 'kill (c-kill pid sig))) ;; sigprocmask with sigset_t management - ;; sigset_t is 128 bytes on Linux (1024 bits) - (define SIGSET_SIZE 128) + ;; sigset_t: 16 bytes on FreeBSD, 128 bytes on Linux (1024 bits) + (define SIGSET_SIZE (if *freebsd?* 16 128)) (define c-sigemptyset (foreign-procedure "sigemptyset" (void*) int)) (define c-sigfillset (foreign-procedure "sigfillset" (void*) int)) @@ -558,17 +562,20 @@ (define (free-stat stat-buf) (foreign-free stat-buf)) - ;; Linux x86_64 struct stat field offsets + ;; struct stat field offsets (first 6 fields match Linux and FreeBSD x86_64) (define (stat-dev buf) (foreign-ref 'unsigned-64 buf 0)) ;; st_dev (define (stat-ino buf) (foreign-ref 'unsigned-64 buf 8)) ;; st_ino (define (stat-nlink buf) (foreign-ref 'unsigned-64 buf 16)) ;; st_nlink (define (stat-mode buf) (foreign-ref 'unsigned-32 buf 24)) ;; st_mode (define (stat-uid buf) (foreign-ref 'unsigned-32 buf 28)) ;; st_uid (define (stat-gid buf) (foreign-ref 'unsigned-32 buf 32)) ;; st_gid - (define (stat-size buf) (foreign-ref 'integer-64 buf 48)) ;; st_size - (define (stat-atime buf) (foreign-ref 'integer-64 buf 72)) ;; st_atim.tv_sec - (define (stat-mtime buf) (foreign-ref 'integer-64 buf 88)) ;; st_mtim.tv_sec - (define (stat-ctime buf) (foreign-ref 'integer-64 buf 104)) ;; st_ctim.tv_sec + ;; Remaining fields differ: FreeBSD has st_atim at 48, st_mtim at 64, + ;; st_ctim at 80, st_size at 112. Linux has st_size at 48, st_atim at 72, + ;; st_mtim at 88, st_ctim at 104. + (define (stat-size buf) (foreign-ref 'integer-64 buf (if *freebsd?* 112 48))) + (define (stat-atime buf) (foreign-ref 'integer-64 buf (if *freebsd?* 48 72))) + (define (stat-mtime buf) (foreign-ref 'integer-64 buf (if *freebsd?* 64 88))) + (define (stat-ctime buf) (foreign-ref 'integer-64 buf (if *freebsd?* 80 104))) ;; File type checks (from st_mode) (define S_IFMT #o170000) --- a/lib/std/os/signal-channel.sls +++ b/lib/std/os/signal-channel.sls @@ -26,7 +26,8 @@ (guard (e [#t #f]) (load-shared-object "libc.so")))) (define _libc2 (guard (e [#t #f]) (load-shared-object ""))) - (define SIGSET_SIZE 128) + (define *freebsd?* (memq (machine-type) '(a6fb ta6fb i3fb ti3fb arm64fb))) + (define SIGSET_SIZE (if *freebsd?* 16 128)) ;; sizeof(sigset_t): FreeBSD=16, Linux=128 (define c-sigemptyset (foreign-procedure "sigemptyset" (void*) int)) (define c-sigaddset (foreign-procedure "sigaddset" (void* int) int)) (define c-sigprocmask (foreign-procedure "sigprocmask" (int void* void*) int)) --- a/lib/std/os/signalfd.sls +++ b/lib/std/os/signalfd.sls @@ -37,10 +37,11 @@ ;; ========== Constants ========== - (define SFD_CLOEXEC #x80000) ;; same as O_CLOEXEC - (define SFD_NONBLOCK #x800) ;; same as O_NONBLOCK + (define *freebsd?* (memq (machine-type) '(a6fb ta6fb i3fb ti3fb arm64fb))) + (define SFD_CLOEXEC (if *freebsd?* #x100000 #x80000)) ;; same as O_CLOEXEC + (define SFD_NONBLOCK (if *freebsd?* #x4 #x800)) ;; same as O_NONBLOCK - (define SIGSET_SIZE 128) ;; sizeof(sigset_t) on Linux x86_64 + (define SIGSET_SIZE (if *freebsd?* 16 128)) ;; sizeof(sigset_t): FreeBSD=16, Linux=128 (define SIGNALFD_SIGINFO_SIZE 128) ;; sizeof(struct signalfd_siginfo) (define SIG_BLOCK 0) @@ -60,6 +61,7 @@ (foreign-procedure "__errno_location" () void*))) (define (get-errno) (foreign-ref 'int (c-errno-location) 0)) (define EINTR 4) + (define EAGAIN (if *freebsd?* 35 11)) ;; ========== signalfd record ========== @@ -127,7 +129,7 @@ (foreign-ref 'unsigned-32 buf 0)] [(and (< n 0) (= (get-errno) EINTR)) (loop)] - [(and (< n 0) (= (get-errno) 11)) ;; EAGAIN + [(and (< n 0) (= (get-errno) EAGAIN)) #f] ;; no signal pending (non-blocking mode) [(= n 0) #f] ;; EOF --- a/lib/std/repl/server.sls +++ b/lib/std/repl/server.sls @@ -86,16 +86,22 @@ (define AF_INET 2) (define SOCK_STREAM 1) - (define SOL_SOCKET 1) - (define SO_REUSEADDR 2) + (define *freebsd?* (memq (machine-type) '(a6fb ta6fb i3fb ti3fb arm64fb))) + (define SOL_SOCKET (if *freebsd?* #xffff 1)) + (define SO_REUSEADDR (if *freebsd?* 4 2)) (define F_GETFL 3) (define F_SETFL 4) - (define O_NONBLOCK 2048) + (define O_NONBLOCK + (if (memq (machine-type) '(a6fb ta6fb i3fb ti3fb arm64fb)) #x4 #x800)) (define (make-sockaddr-in port) ;; struct sockaddr_in: family(2) + port(2) + addr(4) + zero(8) = 16 bytes (let ([buf (make-bytevector 16 0)]) - (bytevector-u16-native-set! buf 0 AF_INET) + (if *freebsd?* + (begin + (bytevector-u8-set! buf 0 16) ;; sin_len = sizeof(sockaddr_in) + (bytevector-u8-set! buf 1 AF_INET)) ;; sin_family (uint8) + (bytevector-u16-native-set! buf 0 AF_INET)) (bytevector-u16-set! buf 2 (c-htons port) 'big) ;; INADDR_ANY = 0.0.0.0 (already zeroed) buf)) --- a/lib/std/web/fastcgi.sls +++ b/lib/std/web/fastcgi.sls @@ -51,15 +51,17 @@ (define AF_INET 2) (define SOCK_STREAM 1) - (define SOL_SOCKET 1) - (define SO_REUSEADDR 2) + (define SOL_SOCKET (if *freebsd?* #xffff 1)) + (define SO_REUSEADDR (if *freebsd?* 4 2)) (define INADDR_ANY 0) (define SOCKADDR_IN_SIZE 16) + (define *freebsd?* (memq (machine-type) '(a6fb ta6fb i3fb ti3fb arm64fb))) (define EINTR 4) - (define EAGAIN 11) + (define EAGAIN (if *freebsd?* 35 11)) (define F_GETFL 3) (define F_SETFL 4) - (define O_NONBLOCK #x800) + (define O_NONBLOCK + (if (memq (machine-type) '(a6fb ta6fb i3fb ti3fb arm64fb)) #x4 #x800)) (define *retry-delay* (make-time 'time-duration 10000000 0)) @@ -127,7 +129,11 @@ (define (make-sockaddr-in address port) (let ((buf (make-bytevector SOCKADDR_IN_SIZE 0))) - (bytevector-u16-set! buf 0 AF_INET (native-endianness)) + (if *freebsd?* + (begin + (bytevector-u8-set! buf 0 16) ;; sin_len = sizeof(sockaddr_in) + (bytevector-u8-set! buf 1 AF_INET)) ;; sin_family (uint8) + (bytevector-u16-set! buf 0 AF_INET (native-endianness))) (bytevector-u16-set! buf 2 (c-htons port) (native-endianness)) (if (string=? address "0.0.0.0") (bytevector-u32-set! buf 4 INADDR_ANY (native-endianness)) --- a/lib/std/web/rack.sls +++ b/lib/std/web/rack.sls @@ -46,15 +46,17 @@ (define AF_INET 2) (define SOCK_STREAM 1) - (define SOL_SOCKET 1) - (define SO_REUSEADDR 2) + (define SOL_SOCKET (if *freebsd?* #xffff 1)) + (define SO_REUSEADDR (if *freebsd?* 4 2)) (define INADDR_ANY 0) (define SOCKADDR_IN_SIZE 16) + (define *freebsd?* (memq (machine-type) '(a6fb ta6fb i3fb ti3fb arm64fb))) (define EINTR 4) - (define EAGAIN 11) + (define EAGAIN (if *freebsd?* 35 11)) (define F_GETFL 3) (define F_SETFL 4) - (define O_NONBLOCK #x800) + (define O_NONBLOCK + (if (memq (machine-type) '(a6fb ta6fb i3fb ti3fb arm64fb)) #x4 #x800)) (define *retry-delay* (make-time 'time-duration 10000000 0)) @@ -137,8 +139,12 @@ (define (make-sockaddr-in address port) (let ((buf (make-bytevector SOCKADDR_IN_SIZE 0))) - ;; sin_family = AF_INET (offset 0, 2 bytes little-endian on Linux) - (bytevector-u16-set! buf 0 AF_INET (native-endianness)) + ;; sin_family = AF_INET + (if *freebsd?* + (begin + (bytevector-u8-set! buf 0 16) ;; sin_len = sizeof(sockaddr_in) + (bytevector-u8-set! buf 1 AF_INET)) ;; sin_family (uint8) + (bytevector-u16-set! buf 0 AF_INET (native-endianness))) ;; sin_port (offset 2, network byte order) (bytevector-u16-set! buf 2 (c-htons port) (native-endianness)) ;; sin_addr (offset 4)