shithub: mc

Download patch

ref: 2c8985573c67d496b8e0b717cbbdba819235ef33
parent: d5b8eb377b49496a6b000104cfa415f90f1a9548
author: Ori Bernstein <[email protected]>
date: Wed Jan 8 14:32:20 EST 2014

Add initial support for execv() calls

--- a/libstd/start-osx.s
+++ b/libstd/start-osx.s
@@ -7,6 +7,10 @@
 .envlen:
 .quad 0 /* env ptr */
 
+.globl _std$__cenvp
+_std$__cenvp:
+.quad 0
+
 .text
 /*
  * counts the length of the string pointed to
@@ -68,6 +72,9 @@
 start:
 	/* turn args into a slice */
 	movq	%rsp,%rbp
+        /* store envp for some syscalls to use without converting */
+	movq	16(%rbp,%rax,8), %rbx	/* envp = argv + 8*argc + 8 */
+        movq    %rbx,_std$__cenvp(%rip)
 	/* stack allocate sizeof(byte[:])*(argc + len(envp)) */
 	movq	(%rbp),%rax
 	leaq	16(%rbp,%rax,8), %rbx	/* envp = argv + 8*argc + 8 */
--- a/libstd/sys-linux.myr
+++ b/libstd/sys-linux.myr
@@ -442,7 +442,12 @@
 	const exit	: (status:int -> void)
 	const getpid	: ( -> int64)
 	const kill	: (pid:int64, sig:int64 -> int64)
+	const fork	: (-> int64)
+	const wait4	: (pid:int64, loc:int64#, opt : int64, usage:rusage#	-> int64)
+	const waitpid	: (pid:int64, loc:int64#, opt : int64	-> int64)
+	const execv	: (cmd : byte[:], args : byte[:][:])
 
+
 	/* fd manipulation */
 	const open	: (path:byte[:], opts:fdopt, mode:int64 -> fd)
 	const close	: (fd:fd -> int64)
@@ -479,6 +484,19 @@
 const exit	= {status;		syscall(Sysexit, status castto(int64))}
 const getpid	= {;			-> syscall(Sysgetpid, 1)}
 const kill	= {pid, sig;		-> syscall(Syskill, pid, sig)}
+const fork	= {;			-> syscall(Sysfork)}
+const wait4	= {pid, loc, opt, use;	-> syscall(Syswait4, pid, loc, opt, use)}
+const waitpid	= {pid, loc, opt;	-> 
+	var rusage
+	-> wait4(pid, loc, opt, &rusage)
+}
+const execv	= {cmd, args
+	var buf : byte#[1024] /* FIXME: right now, we only support 1023 args. */
+	for a in args
+		buf[i++] = cstring(buf)
+	;;
+}
+
 
 /* fd manipulation */
 const open	= {path, opts, mode;	-> syscall(Sysopen, cstring(path), opts, mode) castto(fd)}
--- a/libstd/sys-osx.myr
+++ b/libstd/sys-osx.myr
@@ -52,6 +52,12 @@
 		qspare1	: int64
 	;;
 
+	type rusage = struct
+		utime	: timeval	/* user time */
+		stime	: timeval	/* system time */
+		_opaque	: uint64[14]	/* padding (darwin-specific data) */
+	;;
+
 	type utsname = struct
 		system	: byte[256]
 		node	: byte[256]
@@ -478,11 +484,20 @@
 
 	extern const syscall : (sc:scno, args:... -> int64)
 	extern const cstring : (str : byte[:] -> byte#)
+	extern const alloca : (sz : size -> byte#)
+	extern const __cenvp : byte##
 
 	/* process control */
 	const exit	: (status:int -> void)
 	const getpid	: ( -> int64)
 	const kill	: (pid:int64, sig:int64 -> int64)
+	const fork	: (-> int64)
+	const wait4	: (pid:int64, loc:int64#, opt : int64, usage:rusage#	-> int64)
+	const waitpid	: (pid:int64, loc:int64#, opt : int64	-> int64)
+	const execv	: (cmd : byte[:], args : byte[:][:] -> int64)
+	const execve	: (cmd : byte[:], args : byte[:][:], env : byte[:][:] -> int64)
+	const execvp	: (cmd : byte[:], args : byte[:][:] -> int64)
+	const execvpe	: (cmd : byte[:], args : byte[:][:], env : byte[:][:] -> int64)
 
 	/* fd manipulation */
 	const open	: (path:byte[:], opts:fdopt, mode:int64 -> fd)
@@ -522,6 +537,22 @@
 const exit	= {status;		syscall(Sysexit, status castto(int64))}
 const getpid	= {;			-> syscall(Sysgetpid, 1)}
 const kill	= {pid, sig;		-> syscall(Syskill, pid, sig)}
+const fork	= {;			-> syscall(Sysfork)}
+const wait4	= {pid, loc, opt, usage;	-> syscall(Syswait4, pid, loc, opt, usage)}
+const waitpid	= {pid, loc, opt;
+	var rusage
+	-> wait4(pid, loc, opt, &rusage)
+}
+const execv	= {cmd, args
+	var cargs, i
+
+	cargs = (alloca(sizeof(byte#)*(args.len + 1)) castto(byte##))[:args.len]
+	for i = 0; i < args.len; i++
+		cargs[i] = cstring(args[i])
+	;;
+	cargs[args.len] = 0 castto(byte#)
+	-> syscall(Sysexecve, cmd castto(byte#), cargs, __cenvp)
+}
 
 /* fd manipulation */
 const open	= {path, opts, mode;	-> syscall(Sysopen, cstring(path), opts, mode) castto(fd)}
--- a/libstd/util.s
+++ b/libstd/util.s
@@ -30,3 +30,17 @@
 	pushq %r15              /* ret addr */
 	ret
 
+.globl std$alloca
+.globl _std$alloca
+_std$alloca:
+std$alloca:
+	movq (%rsp),%r15	/* ret addr */
+	movq 8(%rsp),%rbx	/* len */
+	movq %rsp,%rax          /* top of stack (return value) */
+	
+	/* get stack space */
+	subq $8,%rsp		/* "unpop" the args for return */
+	subq %rbx,%rsp          /* get stack space */
+
+	pushq %r15              /* ret addr */
+	ret