code wiki / (root) / nx_unix_socket.nx

nx_unix_socket.nx source

↩ module page · 60 lines · 1931 B

1// nx_unix_socket.nx -- Unix-domain stream-socket primitive. 2// 3// Connects to a filesystem path serving as an AF_UNIX socket 4// endpoint. Used by X11 (the wire-protocol bridge between bits-up 5// NishiLang and a WSLg/X11 server on Windows), by D-Bus once we 6// touch IPC, and by any future local-IPC client. 7// 8// Bits-up: we open SYS_SOCKET + SYS_CONNECT directly, no libc, 9// no glibc-style getaddrinfo dance, no third-party tool. 10// 11// API: 12// nx_unix_connect(path) -> i64 13// Opens AF_UNIX SOCK_STREAM socket, connects to `path`, and 14// returns the connected fd on success. Returns a negative 15// value (typically a kernel errno code, e.g. -2 ENOENT) on 16// failure. 17// 18// license_tier: ORIGINAL 19// lineage_id: nishi_unix_socket_q10 20 21import "nx_syscalls.nx" 22 23const NX_AF_UNIX: i64 = 1 24 25// Build sockaddr_un = [sa_family(2)][sun_path(108)]. We zero-pad 26// the path region and write the caller's NUL-terminated path bytes. 27// Returns the connected fd or a negative errno. 28func nx_unix_connect(path: *u8) -> i64 { 29 let fd: i64 = sys_socket(NX_AF_UNIX, SOCK_STREAM, 0) 30 if fd < 0 { return fd } 31 32 // Allocate sockaddr_un (110 bytes; 2 family + 108 path). 33 let sa: *u8 = sys_mmap(128) 34 var i: i64 = 0 35 while i < 128 { sa[i] = 0; i = i + 1 } 36 // sa_family: little-endian u16 = 1 37 sa[0] = (NX_AF_UNIX & 0xff) as u8 38 sa[1] = ((NX_AF_UNIX >> 8) & 0xff) as u8 39 // sun_path: copy NUL-terminated path into bytes [2..] 40 var p: i64 = 0 41 while path[p] != 0 { 42 if p >= 107 { return 0 - 36 } // -ENAMETOOLONG 43 sa[2 + p] = path[p] 44 p = p + 1 45 } 46 sa[2 + p] = 0 // NUL terminator (already 0 from clear; explicit) 47 48 // addr_len = offsetof(sun_path) + strlen + 1 49 let addr_len: i64 = 2 + p + 1 50 let rc: i64 = sys_connect(fd, sa, addr_len) 51 if rc < 0 { 52 sys_close(fd) 53 return rc 54 } 55 return fd 56} 57 58func main() -> i64 { 59 return 0 60}