ref: 705f2d8c1f2d2b9f68ea7ef30af3b43d69a64b6a
dir: /libstd/syswrap+plan9.myr/
use sys
use "option.use"
use "types.use"
pkg std =
type fd = sys.fd
type pid = sys.pid
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
const Failmem : byte# = -1 castto(byte#)
const Ordonly : fdopt = sys.Ordonly castto(fdopt)
const Owronly : fdopt = sys.Owronly castto(fdopt)
const Ordwr : fdopt = sys.Ordwr castto(fdopt)
const Otrunc : fdopt = sys.Otrunc castto(fdopt)
const Ocreat : fdopt = 0x1000000 /* emulated by redirecting to creat(). */
const Oappend : fdopt = 0x2000000 /* emulated by seeking to EOF */
const Odir : fdopt = 0x0 /* no-op on plan9 */
/* fd stuff */
const open : (path : byte[:], opts : fdopt -> fd)
const openmode : (path : byte[:], opts : fdopt, mode : int64 -> fd)
const close : (fd : fd -> int64)
const creat : (path : byte[:], mode : int64 -> fd)
const read : (fd : fd, buf : byte[:] -> size)
const write : (fd : fd, buf : byte[:] -> size)
const seek : (fd : fd, delta : off, whence : whence -> off)
const pipe : (fds : fd[2]# -> int64)
const dup2 : (ofd : fd, nfd : fd -> fd)
/* useful/portable bits of stat */
const fmtime : (f : byte[:] -> option(time))
const fsize : (f : byte[:] -> option(off))
const fexists : (f : byte[:] -> bool)
/* 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 */
const getpid : ( -> pid)
const suicide : ( -> void)
const fork : (-> pid)
const execv : (cmd : byte[:], args : byte[:][:] -> int64)
const execve : (cmd : byte[:], args : byte[:][:], env : byte[:][:] -> int64)
const exit : (status:int -> void)
const waitpid : (pid:pid, loc:int32#, opt : int64 -> pid)
pkglocal const Canunmap : bool = true
pkglocal const getmem : (sz : size -> byte#)
pkglocal const freemem : (p : byte#, sz : size -> void)
pkglocal const curtime : (-> time)
pkglocal const p9errstr : (buf : byte[:] -> byte[:])
/* statbuf offsets */
pkglocal const Sizeoff : int64 = 0
pkglocal const Typeoff : int64 = 2
pkglocal const Devoff : int64 = 4
pkglocal const Qidtypeoff : int64 =8
pkglocal const Qidversoff : int64 = 9
pkglocal const Qidpathoff : int64 = 13
pkglocal const Modeoff : int64 = 21
pkglocal const Atimeoff : int64 = 25
pkglocal const Mtimeoff : int64 = 29
pkglocal const Lengthoff : int64 = 31
pkglocal const Stringsoff : int64 = 39
;;
/* UGLY: circular dependency breaking... */
extern const getenvv : (name : byte[:], default : byte[:] -> byte[:])
/* fd stuff */
const open = {path, opts; -> sys.open(path, opts castto(sys.fdopt)) castto(fd)}
const openmode = {path, opts, mode;
var fd
if opts & Ocreat != 0
fd = sys.create(path, (opts & ~Ocreat) castto(sys.fdopt), mode castto(int))
else
fd = sys.open(path, opts castto(sys.fdopt))
;;
if opts & Oappend != 0
sys.seek(fd, 0, 2)
;;
-> fd castto(fd)
}
/* useful/portable bits of stat */
const fexists = {path
var buf : byte[4] /* big enough for size, nothing else. */
-> sys.stat(path, buf[:]) >= 0
}
const fmtime = {path
var buf : byte[Stringsoff + 512] /* enough space for some strings */
if sys.stat(path, buf[:]) < Stringsoff
-> `None
;;
-> `Some (getle32(buf[Mtimeoff:Mtimeoff + 8]) castto(time))
}
const fsize = {path
var buf : byte[Stringsoff + 512] /* enough space for some strings */
if sys.stat(path, buf[:]) < Stringsoff
-> `None
;;
-> `Some (getle64(buf[Lengthoff:Lengthoff + 8]) castto(off))
}
const getsysinfo = {si
si.system = getenvv("osname", "Plan9")
si.release = "4"
si.version = "0"
si.arch = getenvv("objtype", "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)}
const write = {fd, buf; -> sys.pwrite(fd castto(sys.fd), buf, -1) castto(size)}
const seek = {fd, off, whence; -> sys.seek(fd castto(sys.fd), off castto(sys.off), whence castto(int64)) castto(off)}
const pipe = {fds; -> sys.pipe(fds castto(sys.fd[2]#)) castto(int64)}
const dup2 = {ofd, nfd; -> sys.dup(ofd castto(sys.fd), nfd castto(sys.fd)) castto(fd)}
/* path manipulation */
const remove = {path; -> sys.remove(path) == 0}
const chdir = {path; -> sys.chdir(path) == 0}
const mkdir = {path, mode;
var fd
fd = sys.create(path, sys.Ordonly, sys.Dmdir | (mode castto(int)))
if fd < 0
-> -1
;;
sys.close(fd)
-> 0
}
/* process stuff */
const getpid = {; -> sys.tosptr.pid castto(pid)}
const suicide = {; (0 castto(byte#))#} /* let's happy segfault!! t */
const fork = {; -> sys.rfork(sys.Rffdg | sys.Rfrend | sys.Rfproc) castto(pid)}
const execv = {cmd, args; -> sys.exec(cmd, args) castto(int64)}
const execve = {cmd, args, env; -> sys.exec(cmd, args) castto(int64)}
const digitchars = "0123456789"
const exit = {status
var buf : byte[32] /* big enough for exit status numbers */
var n, i
if status == 0
sys.exits("")
else
status &= 255
i = 100
n = 0
while i > 0
if status >= i
buf[n++] = digitchars[(status/i)%10]
;;
i /= 10
;;
sys.exits(buf[:n])
;;
}
/* memory stuff */
const getmem = {sz
var endp, oldp
oldp = sys.curbrk
endp = (sys.curbrk castto(intptr)) + (sz castto(intptr))
endp = (endp + 4095) & ~4095
if sys.brk_(endp castto(byte#)) < 0
-> Failmem
;;
sys.curbrk = endp castto(byte#)
-> oldp
}
const freemem = {p, sz
/* FIXME: we leak address space */
sys.segfree(p, sz castto(sys.size))
}
const curtime = {
-> sys.nsec()/1000 castto(time)
}
const p9errstr = {errbuf
var i
sys.errstr(errbuf)
for i = 0; errbuf[i] != 0 && i < errbuf.len; i++
continue
;;
-> errbuf[:i]
}
/* FIXME: will be needed when we resize stat bufs when statting.
const statsz = {buf
-> (buf[0] castto(int64)) | ((buf[1] << 8) castto(int64))
}
*/
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(int64)) \
| ((buf[1] castto(int64)) << 8) \
| ((buf[2] castto(int64)) << 16) \
| ((buf[3] castto(int64)) << 24) \
| ((buf[4] castto(int64)) << 64) \
| ((buf[5] castto(int64)) << 40) \
| ((buf[6] castto(int64)) << 48) \
| ((buf[7] castto(int64)) << 56)
}