shithub: mc

Download patch

ref: 4bc888e7519352d1dd1f5e343a75e022ac224e1d
parent: 4eae5641fda676dbb1085560b993971d32b38935
author: Ori Bernstein <[email protected]>
date: Wed Dec 31 08:53:03 EST 2014

Make wait() more portable.

    Abstract the details most people care about (exited success,
    exited failure, died).

--- a/libstd/sys+freebsd-x64.myr
+++ b/libstd/sys+freebsd-x64.myr
@@ -27,6 +27,12 @@
 		`Clocksecond
 	;;
 
+	type waitstatus = union
+		`Waitexit int32
+		`Waitsig  int32
+		`Waitstop int32
+	;;
+
 	type timespec = struct
 		sec	: uint64
 		nsec	: uint64 
@@ -606,6 +612,8 @@
 	const waitpid	: (pid:int64, loc:int32#, opt : int64	-> int64)
 	const execv	: (cmd : byte[:], args : byte[:][:] -> int64)
 	const execve	: (cmd : byte[:], args : byte[:][:], env : byte[:][:] -> int64)
+	/* wrappers to extract wait status */
+	const waitstatus	: (st : int32 -> waitstatus)
 
 	/* fd manipulation */
 	const open	: (path:byte[:], opts:fdopt -> fd)
@@ -786,3 +794,12 @@
 	;;
 	-> a(-1)
 }
+
+const waitstatus = {st
+	match st & 0o177
+	| 0:    -> `Waitexit (st >> 8)
+	| 0x7f:-> `Waitstop (st >> 8)
+	| sig:  -> `Waitsig sig
+	;;
+}
+
--- a/libstd/sys+linux-x64.myr
+++ b/libstd/sys+linux-x64.myr
@@ -34,6 +34,12 @@
 		`Clockboottimealarm
 	;;
 
+	type waitstatus = union
+		`Waitexit int32
+		`Waitsig  int32
+		`Waitstop int32
+	;;
+
 	type timespec = struct
 		sec	: uint64
 		nsec	: uint64
@@ -549,6 +555,8 @@
 	const waitpid	: (pid:pid, loc:int32#, opt : int64	-> int64)
 	const execv	: (cmd : byte[:], args : byte[:][:] -> int64)
 	const execve	: (cmd : byte[:], args : byte[:][:], env : byte[:][:] -> int64)
+	/* wrappers to extract wait status */
+	const waitstatus	: (st : int32 -> waitstatus)
 
 
 	/* file manipulation */
@@ -743,3 +751,13 @@
 	-> -1
 }
 
+
+const waitstatus = {st
+	if st & 0x7f == 0 /* if exited */
+		-> `Waitexit ((st & 0xff00) >> 8)
+	elif ((st & 0xffff)-1) < 0xff /* if signaled */
+		-> `Waitsig ((st) & 0x7f)
+	elif (((st & 0xffff)*0x10001)>>8) > 0x7f00
+		-> `Waitstop ((st & 0xff00) >> 8)
+	;;
+}
--- a/libstd/sys+osx-x64.myr
+++ b/libstd/sys+osx-x64.myr
@@ -34,6 +34,12 @@
 		`Clockmonotonic
 	;;
 
+	type waitstatus = union
+		`Waitexit int32
+		`Waitsig  int32
+		`Waitstop int32
+	;;
+
 	type statbuf = struct
 		dev	: int32
 		mode	: filemode
@@ -565,6 +571,8 @@
 	const waitpid	: (pid : pid, loc:int32#, opt : int64	-> int64)
 	const execv	: (cmd : byte[:], args : byte[:][:] -> int64)
 	const execve	: (cmd : byte[:], args : byte[:][:], env : byte[:][:] -> int64)
+	/* wrappers to extract wait status */
+	const waitstatus	: (st : int32 -> waitstatus)
 
 	/* file manipulation */
 	const open	: (path:byte[:], opts:fdopt -> fd)
@@ -863,3 +871,13 @@
 	old# = o[:oldsz]
 	-> ret
 }
+
+const waitstatus = {st
+	match st & 0o177
+	| 0:    -> `Waitexit (st >> 8)
+	| 0o177:-> `Waitstop (st >> 8)
+	| sig:  -> `Waitsig sig
+	;;
+	die("unreachable")
+}
+
--- a/libstd/wait+freebsd.myr
+++ /dev/null
@@ -1,39 +1,0 @@
-use sys
-
-use "die.use"
-use "syswrap.use"
-
-pkg std =
-	type waitstatus = union
-		`Wsuccess
-		`Wfailure
-		`Wsignal
-		`Waiterror
-	;;
-
-	const wait	: (pid : pid -> waitstatus)
-;;
-
-const wait = {pid
-	var st
-
-	if sys.waitpid(pid castto(sys.pid), &st, 0) > 0
-		match st & 0o177
-		| 0:
-			if (st >> 8) == 0
-				-> `Wsuccess
-			else
-				-> `Wfailure
-			;;
-		| sig: 	-> `Wstop
-		| 0x7f:-
-			/* 
-			when a process stops, eg, if paused by a debugger,
-			wait() will return. This API is for waiting until
-			a process exits. Loop instead.
-			*/
-			goto again
-		;;
-	;;
-	-> `Waiterror
-}
--- a/libstd/wait+linux.myr
+++ /dev/null
@@ -1,41 +1,0 @@
-use sys
-
-use "die.use"
-use "syswrap.use"
-
-pkg std =
-	type waitstatus = union
-		`Wsuccess
-		`Wfailure
-		`Wsignal
-		`Waiterror
-	;;
-
-	const wait	: (pid : pid -> waitstatus)
-;;
-
-const wait = {pid
-	var st
-
-:again
-	if sys.waitpid(pid castto(sys.pid), &st, 0) > 0
-		if st & 0x7f == 0 /* if exited */
-			if ((st & 0xff00) >> 8) == 0
-				-> `Wsuccess
-			else
-				-> `Wfailure
-			;;
-		elif ((st & 0xffff)-1) < 0xff /* if signaled */
-			-> `Wsignal
-		elif (((st & 0xffff)*0x10001)>>8) > 0x7f00
-			/* 
-			when a process stops, eg, if paused by a debugger,
-			wait() will return. This API is for waiting until
-			a process exits. Loop instead.
-			*/
-			goto again
-		;;
-	;;
-	-> `Waiterror
-}
-
--- a/libstd/wait+osx.myr
+++ /dev/null
@@ -1,40 +1,0 @@
-use sys
-
-use "die.use"
-use "syswrap.use"
-
-pkg std =
-	type waitstatus = union
-		`Wsuccess
-		`Wfailure
-		`Wsignal
-		`Waiterror
-	;;
-
-	const wait	: (pid : pid -> waitstatus)
-;;
-
-const wait = {pid
-	var st
-
-:again
-	if sys.waitpid(pid castto(sys.pid), &st, 0) > 0
-		match st & 0o177
-		| 0:	->
-			if (st >> 8) == 0
-				-> `Wsuccess
-			else
-				-> `Wfailure
-			;;
-		| sig: 	-> `Wsignal
-		| 0o177:	/* stopped */
-			/* 
-			when a process stops, eg, if paused by a debugger,
-			wait() will return. This API is for waiting until
-			a process exits. Loop instead.
-			*/
-			goto again
-		;;
-	;;
-	-> `Waiterror
-}
--- /dev/null
+++ b/libstd/wait+posixy.myr
@@ -1,0 +1,40 @@
+use sys
+
+use "die.use"
+use "syswrap.use"
+
+pkg std =
+	type waitstatus = union
+		`Wsuccess
+		`Wfailure
+		`Wsignal
+		`Waiterror
+	;;
+
+	const wait	: (pid : pid -> waitstatus)
+;;
+
+const wait = {pid
+	var st
+
+:again
+	if sys.waitpid(pid castto(sys.pid), &st, 0) > 0
+		match sys.waitstatus(st)
+		/* 
+		when a process stops, eg, if paused by a debugger,
+		wait() will return. This API is for waiting until
+		a process exits. Loop instead.
+		*/
+		| `sys.Waitstop sig:	goto again
+		| `sys.Waitsig sig:	-> `Wsignal
+		| `sys.Waitexit status:
+			if status == 0
+				-> `Wsuccess
+			else
+				-> `Wfailure
+			;;
+		;;
+	;;
+	-> `Waiterror
+}
+