code wiki / _hdl_build / nx_proc_ctl_hb.nx

nx_proc_ctl_hb.nx source

↩ module page · 96 lines · 4943 B

1// nx_proc_ctl.nx -- shared sovereign /proc process control: kill-by-name + alive-by-name, EXTRACTED VERBATIM 2// from the proven nx_hostctl scanners so the Publisher's recovery executor reuses them WITHOUT importing the 3// whole supervisor (DRY; nx_hostctl can adopt this later). Matches /proc/<pid>/cmdline. No shell, no pkill. 4// CRITICAL (nx_hostctl lesson): BOUNDED cmdline read into a REUSED buffer, NEVER sys_read_file (4GiB-mmap/call 5// leak -> the next fork ENOMEMs = the old F-class supervisor death). license_tier: ORIGINAL 6import "nx_syscalls.nx" // sys_getdents64 / dirent_reclen / dirent_name / nx_kill / sys_munmap / sys_openat_rd / sys_read / sys_close / sys_mmap 7 8func pc_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 9func pc_atoi(s: *u8) -> i64 { var v: i64=0; var i: i64=0; while s[i]!=(0 as u8) { let c: u8=s[i]; if c<(48 as u8){return v} if c>(57 as u8){return v} v=v*10+((c-(48 as u8)) as i64); i=i+1 } return v } 10func pc_contains(hay: *u8, hn: i64, needle: *u8, nn: i64) -> i64 { 11 if nn==0 { return 1 } 12 var i: i64=0 13 while i+nn<=hn { var k: i64=0; var ok: i64=1; while k<nn { if hay[i+k]!=needle[k]{ok=0;k=nn} k=k+1 } if ok==1 { return 1 } i=i+1 } 14 return 0 15} 16func pc_read_cmdline(path: *u8, buf: *u8, cap: i64) -> i64 { 17 let fd: i64 = sys_openat_rd(path) 18 if fd < 0 { return 0 } 19 var total: i64 = 0 20 var n: i64 = sys_read(fd, buf, cap) 21 while n > 0 { total = total + n; if total >= cap { n = 0 } else { n = sys_read(fd, (buf as i64 + total) as *u8, cap - total) } } 22 sys_close(fd) 23 return total 24} 25 26// scan /proc, kill every process whose /proc/<pid>/cmdline contains `needle`. returns #killed. 27func proc_kill_by_name(needle: *u8, sig: i64) -> i64 { 28 let nn: i64 = pc_slen(needle) 29 let fd: i64 = sys_openat_rd("/proc" as *u8) 30 if fd < 0 { return 0 } 31 let buf: *u8 = sys_mmap(65536); let path: *u8 = sys_mmap(256); let clbuf: *u8 = sys_mmap(8192) 32 var killed: i64 = 0; var run: i64 = 1 33 while run == 1 { 34 let n: i64 = sys_getdents64(fd, buf, 65536) 35 if n <= 0 { run = 0 } else { 36 var off: i64 = 0 37 while off < n { 38 let rec: *u8 = ((buf as i64 + off) as *u8) 39 let reclen: i64 = dirent_reclen(rec) 40 if reclen <= 0 { off = n } else { 41 let name: *u8 = dirent_name(rec) 42 if name[0] >= (48 as u8) { if name[0] <= (57 as u8) { 43 var p: i64 = 0; let pre: *u8 = "/proc/" as *u8 44 var a: i64 = 0; while pre[a]!=(0 as u8){path[p]=pre[a];p=p+1;a=a+1} 45 a = 0; while name[a]!=(0 as u8){path[p]=name[a];p=p+1;a=a+1} 46 let suf: *u8 = "/cmdline" as *u8 47 a = 0; while suf[a]!=(0 as u8){path[p]=suf[a];p=p+1;a=a+1} 48 path[p] = 0 as u8 49 let cln: i64 = pc_read_cmdline(path, clbuf, 8192) 50 if cln > 0 { if pc_contains(clbuf, cln, needle, nn) == 1 { nx_kill(pc_atoi(name), sig); killed = killed + 1 } } 51 } } 52 off = off + reclen 53 } 54 } 55 } 56 } 57 sys_close(fd) 58 sys_munmap(buf, 65536); sys_munmap(path, 256); sys_munmap(clbuf, 8192) 59 return killed 60} 61 62// READ-ONLY: 1 iff any process cmdline contains `needle`. 63func proc_alive_by_name(needle: *u8) -> i64 { 64 let nn: i64 = pc_slen(needle) 65 let fd: i64 = sys_openat_rd("/proc" as *u8) 66 if fd < 0 { return 0 } 67 let buf: *u8 = sys_mmap(65536); let path: *u8 = sys_mmap(256); let clbuf: *u8 = sys_mmap(8192) 68 var alive: i64 = 0; var run: i64 = 1 69 while run == 1 { 70 let n: i64 = sys_getdents64(fd, buf, 65536) 71 if n <= 0 { run = 0 } else { 72 var off: i64 = 0 73 while off < n { 74 let rec: *u8 = ((buf as i64 + off) as *u8) 75 let reclen: i64 = dirent_reclen(rec) 76 if reclen <= 0 { off = n } else { 77 let name: *u8 = dirent_name(rec) 78 if name[0] >= (48 as u8) { if name[0] <= (57 as u8) { 79 var p: i64 = 0; let pre: *u8 = "/proc/" as *u8 80 var a: i64 = 0; while pre[a]!=(0 as u8){path[p]=pre[a];p=p+1;a=a+1} 81 a = 0; while name[a]!=(0 as u8){path[p]=name[a];p=p+1;a=a+1} 82 let suf: *u8 = "/cmdline" as *u8 83 a = 0; while suf[a]!=(0 as u8){path[p]=suf[a];p=p+1;a=a+1} 84 path[p] = 0 as u8 85 let cln: i64 = pc_read_cmdline(path, clbuf, 8192) 86 if cln > 0 { if pc_contains(clbuf, cln, needle, nn) == 1 { alive = 1 } } 87 } } 88 off = off + reclen 89 } 90 } 91 } 92 } 93 sys_close(fd) 94 sys_munmap(buf, 65536); sys_munmap(path, 256); sys_munmap(clbuf, 8192) 95 return alive 96}