code wiki / (root) / nx_daemon.nx

nx_daemon.nx source

↩ module page · 26 lines · 1521 B

1// nx_daemon.nx -- canonical sovereign detached-spawn: launch an elf as a daemon that survives the parent (new 2// session via setsid), the sovereign run_in_background. Importable (no main). fork -> child setsid()s then execve()s; 3// parent gets the child pid. Same sys_fork/nx_setsid/sys_execve nx_hostctl uses to supervise its NAS daemons. 4// license_tier: ORIGINAL 5import "nx_syscalls.nx" 6 7// spawn `elf` with `argv` (a NUL-terminated *i64 array of *u8 pointers) DETACHED. Returns child pid (>0) in the 8// parent, 0 should never be seen (child execve's or exits), <0 on fork failure. envp=0 -> empty environment. 9func daemon_spawn(elf: *u8, argv: *i64) -> i64 { 10 let pid: i64 = sys_fork() 11 if pid == 0 { 12 nx_setsid() 13 // FULLY daemonize: detach the std fds so the child can't die of SIGPIPE when the launcher's pipe closes, 14 // and so it has no controlling terminal. stdin <- /dev/null, stdout+stderr -> /tmp/nxd.log (a real log). 15 let din: i64 = sys_openat_rd("/dev/null" as *u8) 16 let dlog: i64 = sys_openat_wr("/tmp/nxd.log" as *u8, 0x1a4) 17 if din >= 0 { sys_dup3(din, 0, 0) } 18 if dlog >= 0 { sys_dup3(dlog, 1, 0); sys_dup3(dlog, 2, 0) } 19 sys_execve(elf, argv, 0 as *i64) 20 sys_exit(127) // only reached if execve failed 21 } 22 return pid 23} 24 25// build a 2-entry argv [elf, 0] for the common no-args daemon case; argv must be >= 2 i64 slots. 26func daemon_argv0(elf: *u8, argv: *i64) -> i64 { argv[0] = elf as i64; argv[1] = 0; return 0 }