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}