shithub: mc

ref: faebdc376eb7d03cff18cc20d997d328f5fdd9b7
dir: /libstd/syswrap+plan9.myr/

View raw version
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", "amd64")
}

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)
}