shithub: mc

Download patch

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}