ref: a0ab14aa2623261f26d2ee5f60bd240b086a3e7d
parent: 9ed8ab553a8d92893f0417abcc2adbfc3f94e478
parent: dae8be83400216caec8ecda7da7a32f7e48e9a7c
author: Ori Bernstein <[email protected]>
date: Thu Aug 21 20:17:00 EDT 2014
Merge branch 'master' of git+ssh://mimir.eigenstate.org/git/ori/mc Conflicts: libstd/sys-linux.myr
--- a/libstd/Makefile
+++ b/libstd/Makefile
@@ -40,6 +40,7 @@
slput.myr \
slurp.myr \
sort.myr \
+ spork.myr \
strfind.myr \
strjoin.myr \
strsplit.myr \
--- /dev/null
+++ b/libstd/spork.myr
@@ -1,0 +1,59 @@
+use "die.use"
+use "execvp.use"
+use "fmt.use"
+use "sys.use"
+
+pkg std =
+ const spork : (cmd : byte[:][:] -> (pid, fd, fd))
+ const sporkfd : (cmd : byte[:][:], infd : fd, outfd : fd -> pid)
+;;
+
+const spork = {cmd
+ var infds : fd[2], outfds : fd[2]
+ var err
+ var pid
+
+ /* open up pipes */
+ err = pipe(infds[:])
+ if err != 0
+ fatal(1, "Could not create pipes: err %l\n", -err)
+ ;;
+ err = pipe(outfds[:])
+ if err != 0
+ fatal(1, "Could not create pipes: err %l\n", -err)
+ ;;
+
+ pid = sporkfd(cmd, infds[0], outfds[1])
+ /* close unused fd ends */
+ close(infds[0]);
+ close(outfds[1]);
+ -> (pid, infds[1], outfds[0])
+}
+
+const sporkfd = {cmd, infd, outfd
+ var pid
+
+ pid = fork()
+ /* error */
+ if pid == -1
+ fatal(1, "Could not fork to start slave\n")
+ /* child */
+ elif pid == 0
+ /* stdin/stdout for our communication. */
+ if dup2(infd, 0) != 0
+ fatal(1, "unable to set stdin\n")
+ ;;
+ if dup2(outfd, 1) != 1
+ fatal(1, "unable to set stdout\n")
+ ;;
+ close(infd)
+ close(outfd)
+ if execvp(cmd[0], cmd) < 0
+ fatal(1, "failed to exec %s\n")
+ ;;
+ /* parent */
+ else
+ -> pid
+ ;;
+}
+
--- a/libstd/sys-linux.myr
+++ b/libstd/sys-linux.myr
@@ -542,11 +542,11 @@
/* process management */
const exit : (status:int -> void)
- const getpid : ( -> int64)
- const kill : (pid:int64, sig:int64 -> int64)
- const fork : (-> int64)
- const wait4 : (pid:int64, loc:int32#, opt : int64, usage:rusage# -> int64)
- const waitpid : (pid:int64, loc:int32#, opt : int64 -> int64)
+ const getpid : ( -> pid)
+ const kill : (pid:pid, sig:int64 -> int64)
+ const fork : (-> pid)
+ const wait4 : (pid:pid, loc:int32#, opt : int64, usage:rusage# -> int64)
+ 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)
@@ -613,9 +613,9 @@
/* process management */
const exit = {status; syscall(Sysexit, a(status))}
-const getpid = {; -> syscall(Sysgetpid)}
+const getpid = {; -> syscall(Sysgetpid) castto(pid)}
const kill = {pid, sig; -> syscall(Syskill, a(pid), a(sig))}
-const fork = {; -> syscall(Sysfork)}
+const fork = {; -> syscall(Sysfork) castto(pid)}
const wait4 = {pid, loc, opt, usage; -> syscall(Syswait4, a(pid), a(loc), a(opt), a(usage))}
const waitpid = {pid, loc, opt;
var rusage
--- a/libstd/sys-osx.myr
+++ b/libstd/sys-osx.myr
@@ -5,12 +5,14 @@
type scno = int64 /* syscall */
type fdopt = int64 /* fd options */
type fd = int32 /* fd */
+ type pid = int64 /* pid */
type mprot = int64 /* memory protection */
type mopt = int64 /* memory mapping options */
type socktype = int64 /* socket type */
type sockproto = int64 /* socket protocol */
type sockfam = uint8 /* socket family */
- type filemode = uint16
+ type filemode = uint16 /* file permission bits */
+ type kflags = uint16 /* kqueue flags */
type timespec = struct
sec : uint64
@@ -98,6 +100,45 @@
name : byte[0]
;;
+ type kevent = struct
+ ident : intptr /* identifier for this event */
+ filter : int16 /* filter for event */
+ flags : uint16 /* general flags */
+ fflags : uint32 /* filter-specific flags */
+ data : intptr /* filter-specific data */
+ udata : byte# /* opaque user data identifier */
+ ;;
+
+ type kevent64 = struct
+ ident : uint64 /* identifier for this event */
+ filter : int16 /* filter for event */
+ flags : kflags /* general flags */
+ fflags : uint32 /* filter-specific flags */
+ data : int64 /* filter-specific data */
+ udata : uint64 /* opaque user data identifier */
+ ext : uint64[2] /* filter-specific extensions */
+ ;;
+
+ /* kqueue events */
+ const Kevadd : kflags = 0x0001 /* add event to kq (implies enable) */
+ const Kevdelete : kflags = 0x0002 /* delete event from kq */
+ const Kevenable : kflags = 0x0004 /* enable event */
+ const Kevdisable : kflags = 0x0008 /* disable event (not reported) */
+ const Kevreceipt : kflags = 0x0040 /* force EV_ERROR on success, data == 0 */
+
+ /* kqueue flags */
+ const Kevoneshot : kflags = 0x0010 /* only report one occurrence */
+ const Kevclear : kflags = 0x0020 /* clear event state after reporting */
+ const Kevdispatch : kflags = 0x0080 /* disable event after reporting */
+
+ const Kevsysflags : kflags = 0xf000 /* reserved by system */
+ const Kevflag0 : kflags = 0x1000 /* filter-specific flag */
+ const Kevflag1 : kflags = 0x2000 /* filter-specific flag */
+
+ /* kqueue returned values */
+ const Keveof : kflags = 0x8000 /* eof detected */
+ const Keverror : kflags = 0x4000 /* error, data contains errno */
+
/* open options */
const Ordonly : fdopt = 0x0
const Owronly : fdopt = 0x1
@@ -513,11 +554,11 @@
/* 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:int32#, opt : int64, usage:rusage# -> int64)
- const waitpid : (pid:int64, loc:int32#, opt : int64 -> int64)
+ const getpid : ( -> pid)
+ const kill : (pid : pid, sig:int64 -> int64)
+ const fork : (-> pid)
+ const wait4 : (pid : pid, loc:int32#, opt : int64, usage:rusage# -> int64)
+ 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)
@@ -538,7 +579,16 @@
/* fd stuff */
const pipe : (fd : fd[:] -> int64)
+ const dup : (fd : fd -> fd)
+ const dup2 : (src : fd, dst : fd -> fd)
+ /* kqueue */
+ const kqueue : (-> fd)
+ const kevent : (q : fd, cl : kevent[:], el : kevent[:], flg : kflags, timeout : timespec# -> int64)
+ const kevent64 : (q : fd, cl : kevent64[:], el : kevent64[:], flg : kflags, timeout : timespec# -> int64)
+
+
+
/* networking */
const socket : (dom : sockfam, stype : socktype, proto : sockproto -> fd)
const connect : (sock : fd, addr : sockaddr#, len : size -> int)
@@ -643,7 +693,28 @@
}
const getdirentries64 = {fd, buf, basep; -> syscall(Sysgetdirentries64, fd, buf castto(byte#), buf.len castto(size), basep)}
+/* fd stuff */
const pipe = {fd; -> __osx_pipe(fd castto(fd#))}
+const dup = {fd; -> syscall(Sysdup, fd castto(uint64)) castto(fd)}
+const dup2 = {src, dst; -> syscall(Sysdup2, src castto(uint64), dst castto(uint64)) castto(fd)}
+
+/* kqueueueueueueue */
+const kqueue = {; -> syscall(Syskqueue) castto(fd)}
+const kevent = {q, cl, el, flg, timeout
+ -> syscall(Syskevent, q castto(uint64), \
+ cl castto(kevent#), cl.len castto(uint64), \
+ el castto(kevent#), el.len castto(uint64), \
+ flg castto(uint64), \
+ timeout)
+}
+
+const kevent64 = {q, cl, el, flg, timeout
+ -> syscall(Syskevent, q castto(uint64), \
+ cl castto(kevent#), cl.len castto(uint64), \
+ el castto(kevent#), el.len castto(uint64), \
+ flg castto(uint64), \
+ timeout)
+}
/* networking */
const socket = {dom, stype, proto; -> syscall(Syssocket, dom castto(int64), stype, proto) castto(fd) }