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}