ref: a986d1d8ae4c6f75384b62347c733a226edcafba
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" 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(pidhash, pideq) 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, xpid, sp sp = strsplit(status, " ") if sp.len == 0 slfree(sp) -> (`Wfailure, -1) ;; match intparse(sp[0]) | `Some pid: xpid = pid if sp.len == 4 || (sp.len == 5 && sp[4].len > 0) /* we exited with nil */ st = `Wsuccess elif sp.len == 5 /* we have a status */ st = `Wfailure else /* we have a malformed await message */ st = `Waiterror ;; | `None: xpid = -1 st = `Waiterror ;; slfree(sp) -> (st, xpid) } const pidhash = {x; -> inthash(x castto(int32))} const pideq = {a, b; -> a == b}