code wiki / (root) / nx_pipe.nx

nx_pipe.nx source

↩ module page · 70 lines · 2218 B

1// nx_pipe.nx -- pipe(2) + pipe2(2) wrappers. 2// 3// Pipes are how forked processes communicate: parent fork()s, 4// child write to pipe[1], parent reads from pipe[0]. The build 5// tool pattern is: 6// 7// pipe(fds) # fds[0]=read end, fds[1]=write end 8// pid = fork() 9// if pid == 0: # child 10// close(fds[0]) 11// dup3(fds[1], 1, 0) # redirect stdout 12// execve(...) 13// else: # parent 14// close(fds[1]) 15// n = read(fds[0], buf, ...) 16// 17// Linux RV64 has no sys_pipe -- we use sys_pipe2 (number 59) with 18// flags=0. Optionally O_CLOEXEC to avoid leaking ends across exec. 19// 20// Pairs with nx_fcntl + nx_proc. 21 22// nx_safety_envelope: 23// intended_use: AUTO_APPLIED -- primitive-specific tuning queued 24// sil_target: SIL1 25// evidence: [bulk_applied_2026-05-16, see-file-comment-for-detail] 26// verdict: NOT_YET_EVALUATED 27 28import "syscalls.nx" 29import "nx_fcntl.nx" 30 31const NX_SYS_PIPE2: i64 = 59 32 33// Create a pipe. fds[0] = read end, fds[1] = write end. Returns 34// 0 on success, negative errno on failure. 35func nx_pipe(fds: *i32, flags: i64) -> i64 { 36 return __syscall(NX_SYS_PIPE2, fds as i64, flags, 0, 0, 0, 0) 37} 38 39// Convenience: pipe with both ends marked close-on-exec. 40func nx_pipe_cloexec(fds: *i32) -> i64 { 41 return nx_pipe(fds, NX_O_CLOEXEC) 42} 43 44// ---- self-test --------------------------------------------------- 45 46func main() -> i64 { 47 // Allocate fds[2] (i32 each). 48 let raw: *u8 = sys_mmap(16) 49 let fds: *i32 = raw as *i32 50 51 let r: i64 = nx_pipe(fds, 0) 52 if r < 0 { return __syscall(93, 1, 0, 0, 0, 0, 0) } 53 if fds[0] < 0 { return __syscall(93, 2, 0, 0, 0, 0, 0) } 54 if fds[1] < 0 { return __syscall(93, 3, 0, 0, 0, 0, 0) } 55 56 // Write a sentinel byte to the write end + read it back. 57 let probe: *u8 = sys_mmap(8) 58 probe[0] = 0xAB 59 let nw: i64 = sys_write(fds[1], probe, 1) 60 if nw != 1 { return __syscall(93, 4, 0, 0, 0, 0, 0) } 61 62 let nr: i64 = sys_read(fds[0], probe, 1) 63 if nr != 1 { return __syscall(93, 5, 0, 0, 0, 0, 0) } 64 if probe[0] != 0xAB { return __syscall(93, 6, 0, 0, 0, 0, 0) } 65 66 sys_close(fds[0]) 67 sys_close(fds[1]) 68 69 return 0 70}