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