ref: 0c7eb9f0d093a78520e5cff889dc3fd9d7f6d4c7
dir: /lib/std/wait+plan9.myr/
use sys use "alloc" use "chartype" use "die" use "extremum" use "hashfuncs" use "hasprefix" use "htab" use "intparse" use "option" use "strsplit" use "striter" use "syswrap" use "utf" use "sleq" use "fmt" pkg std = type waitstatus = union `Wsuccess `Wfailure `Wsignalled `Waiterror ;; const wait : (pid : pid -> waitstatus) ;; var statusinit : bool = false var statusmap : htab(pid, waitstatus)# const wait = {pid var buf : byte[512] var xpid, status var n if !statusinit statusmap = mkht(inthash, inteq) statusinit = true ;; match htget(statusmap, pid) | `Some st: htdel(statusmap, pid) -> st | `None: /* nothing */ ;; while true n = sys.await(buf[:]) if n < 0 -> `Waiterror ;; (status, xpid) = parsestatus(buf[:n]) if xpid == pid -> status else htput(statusmap, pid, status) ;; ;; /* impossible */ -> `Waiterror } const parsestatus = {status -> (waitstatus, pid) var st : waitstatus var spbuf : byte[:][5] var xpid, sp sp = bstrsplit(spbuf[:], status, " ") if sp.len == 0 -> (`Wfailure, -1) ;; match intparse(sp[0]) | `Some pid: xpid = pid /* exits(nil) => sp[0] either not present or equal to '' */ if sp.len == 4 || (sp.len == 5 && sleq(sp[4], "''")) st = `Wsuccess elif sp.len == 5 st = `Wfailure else /* we have a malformed await message */ st = `Waiterror ;; | `None: xpid = -1 st = `Waiterror ;; -> (st, xpid) }