ref: 21b91ad9fa7ae830272dc67fbe3150dc30921702
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 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)} /* 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) }