ref: 26f202d8488fa681de64153830846a3544bf9bdb
parent: e91fba6d7709fd6f8dbf0ff9d45721e0924256d1
author: Ori Bernstein <[email protected]>
date: Wed Dec 31 12:03:57 EST 2014
Fix up libstd on plan9.
--- a/libstd/mkfile
+++ b/libstd/mkfile
@@ -65,7 +65,7 @@
units.myr \
utf.myr \
varargs.myr \
- waitstatus.myr \
+ wait.myr \
all:V: lib$STDLIB.a lib$SYSLIB.a
--- a/libstd/syswrap+plan9.myr
+++ b/libstd/syswrap+plan9.myr
@@ -9,6 +9,13 @@
type fdopt = sys.fdopt
type whence = int64
+ type sysinfo = struct
+ system : byte[:]
+ version : byte[:]
+ release : byte[:]
+ arch : byte[:]
+ ;;
+
const Seekset : whence = 0
const Seekcur : whence = 1
const Seekend : whence = 2
@@ -38,8 +45,12 @@
const fmtime : (f : byte[:] -> option(time))
const fsize : (f : byte[:] -> option(off))
+ /* the important bits that uname provides */
+ const getsysinfo : (si : sysinfo# -> void)
+
/* path manipulation */
const mkdir : (path : byte[:], mode : int64 -> int64)
+ const chdir : (path : byte[:] -> bool)
const remove : (path : byte[:] -> bool)
/* process stuff */
@@ -57,6 +68,9 @@
pkglocal const p9errstr : (buf : byte[:] -> byte[:])
;;
+/* UGLY: circular dependency breaking... */
+extern const getenvv : (name : byte[:], default : byte[:] -> byte[:])
+
const Sizeoff = 0
const Typeoff = Sizeoff + 2
const Devoff = Typeoff + 2
@@ -88,24 +102,7 @@
-> fd castto(fd)
}
-const getle32 = {buf
- -> (buf[0] castto(int32)) \
- | ((buf[1] castto(int32)) << 8) \
- | ((buf[2] castto(int32)) << 16) \
- | ((buf[3] castto(int32)) << 24)
-}
-const getle64 = {buf
- -> (buf[0] castto(int32)) \
- | ((buf[1] castto(int32)) << 8) \
- | ((buf[2] castto(int32)) << 16) \
- | ((buf[3] castto(int32)) << 24) \
- | ((buf[4] castto(int32)) << 32) \
- | ((buf[5] castto(int32)) << 40) \
- | ((buf[6] castto(int32)) << 48) \
- | ((buf[7] castto(int32)) << 56)
-}
-
/* useful/portable bits of stat */
const fmtime = {path
var buf : byte[Statprefixsz]
@@ -125,6 +122,12 @@
`Some getle64(buf[Lengthoff:Stringsoff])
}
+const getsysinfo = {si
+ si.system = getenvv("osname", "Plan9")
+ si.release = "4"
+ si.version = "0"
+ si.arch = getenvv("cputype", "unknown")
+}
const close = {fd; -> sys.close(fd castto(sys.fd)) castto(int64)}
const read = {fd, buf; -> sys.pread(fd castto(sys.fd), buf, -1) castto(size)}
@@ -135,6 +138,7 @@
/* path manipulation */
const remove = {path; -> sys.remove(path) == 0}
+const chdir = {path; -> sys.chdir(path) == 0}
const mkdir = {path, mode;
var fd
@@ -173,16 +177,7 @@
;;
}
-/* FIXME: horribly broken. We wait for a pid to exit, and lie about which one. */
-const waitpid = {pid, loc, opt;
- var buf : byte[512]
- var n
- loc# = 0
- n = sys.await(buf[:])
- -> pid
-}
-
/* memory stuff */
const getmem = {sz
var endp, oldp
@@ -214,3 +209,20 @@
-> errbuf[:i]
}
+const getle32 = {buf
+ -> (buf[0] castto(int32)) \
+ | ((buf[1] castto(int32)) << 8) \
+ | ((buf[2] castto(int32)) << 16) \
+ | ((buf[3] castto(int32)) << 24)
+}
+
+const getle64 = {buf
+ -> (buf[0] castto(int32)) \
+ | ((buf[1] castto(int32)) << 8) \
+ | ((buf[2] castto(int32)) << 16) \
+ | ((buf[3] castto(int32)) << 24) \
+ | ((buf[4] castto(int32)) << 32) \
+ | ((buf[5] castto(int32)) << 40) \
+ | ((buf[6] castto(int32)) << 48) \
+ | ((buf[7] castto(int32)) << 56)
+}
\ No newline at end of file
--- a/libstd/wait+plan9.myr
+++ b/libstd/wait+plan9.myr
@@ -1,15 +1,93 @@
use sys
+use "alloc.use"
+use "chartype.use"
use "die.use"
+use "extremum.use"
+use "hashfuncs.use"
+use "hasprefix.use"
+use "htab.use"
+use "intparse.use"
+use "option.use"
+use "strsplit.use"
use "syswrap.use"
+use "utf.use"
pkg std =
type waitstatus = union
- `Waitexit int32
- `Waitsig int32
- `Waitstop int32
+ `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)
+ ;;
+ ;;
+}
+
+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 == 5 /* we have a status */
+ st = `Wfailure
+ elif sp.len == 4 /* we exited with nil */
+ st = `Wsuccess
+ 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}