shithub: mc

ref: a33e94a67326d7774e7373b83597d84ee1eb347b
dir: /lib/sys/sys+plan9-x64.myr/

View raw version
use "systypes"

pkg sys =
	type scno	= int64	/* syscall */
	type pid	= int32 /* process id */
	type fdopt	= int32	/* fd options */
	type fd		= int32	/* fd */
	type rflags	= int32	/* rfork flags */

	type tos = struct
		prof	: prof
		cyclefreq	: uint64
		kcycles	: int64
		pcycles	: int64
		pid	: pid
		clock	: uint32
	;;

	type prof = struct
		pp	: byte#	/* plink */
		next	: byte#	/* plink */
		last	: byte#	/* plink */
		first	: byte#	/* plink */
		pid	: pid	/* plink */
		what	: uint32	/* plink */
	;;

	const Maxerr	: size = 128

	const Oread	: fdopt = 0
	const Owrite	: fdopt = 1
	const Ordwr	: fdopt = 2
	const Oexec	: fdopt = 3

	const Otrunc	: fdopt = 16
	const Ocexec	: fdopt = 32
	const Orclose	: fdopt = 64
	const Oexcl	: fdopt = 0x1000

	const Qtdir	: int  = 0x80
	const Qtappend	: int  = 0x40
	const Qtexcl	: int  = 0x20
	const Qtmount	: int  = 0x10
	const Qtauth	: int  = 0x08
	const Qttmp	: int  = 0x04
	const Qtfile	: int  = 0x00

	const Dmdir	: int = 0x80000000
	const Dmappend	: int = 0x40000000
	const Dmexcl	: int = 0x20000000
	const Dmmount	: int = 0x10000000
	const Dmauth	: int = 0x08000000
	const Dmtmp	: int = 0x04000000
	const Dmread	: int = 0x4
	const Dmwrite	: int = 0x2
	const Dmexec	: int = 0x1

	const Rfnameg	: rflags = 1 << 0
	const Rfenvg	: rflags = 1 << 1
	const Rffdg	: rflags = 1 << 2
	const Rfnoteg	: rflags = 1 << 3
	const Rfproc	: rflags = 1 << 4
	const Rfmem	: rflags = 1 << 5
	const Rfnowait	: rflags = 1 << 6
	const Rfcnameg	: rflags = 1 << 10
	const Rfcenvg	: rflags = 1 << 11
	const Rfcfdg	: rflags = 1 << 12
	const Rfrend	: rflags = 1 << 13
	const Rfnomnt	: rflags = 1 << 14

	const Syssysr1		: scno = 0
	const Sys_errstr	: scno = 1
	const Sysbind		: scno = 2
	const Syschdir		: scno = 3
	const Sysclose		: scno = 4
	const Sysdup		: scno = 5
	const Sysalarm		: scno = 6
	const Sysexec		: scno = 7
	const Sysexits		: scno = 8
	const Sys_fsession	: scno = 9
	const Sysfauth		: scno = 10
	const Sys_fstat		: scno = 11
	const Syssegbrk		: scno = 12
	const Sys_mount		: scno = 13
	const Sysopen		: scno = 14
	const Sys_read		: scno = 15
	const Sysoseek		: scno = 16
	const Syssleep		: scno = 17
	const Sys_stat		: scno = 18
	const Sysrfork		: scno = 19
	const Sys_write		: scno = 20
	const Syspipe		: scno = 21
	const Syscreate		: scno = 22
	const Sysfd2path	: scno = 23
	const Sysbrk_		: scno = 24
	const Sysremove		: scno = 25
	const Sys_wstat		: scno = 26
	const Sys_fwstat	: scno = 27
	const Sysnotify		: scno = 28
	const Sysnoted		: scno = 29
	const Syssegattach	: scno = 30
	const Syssegdetach	: scno = 31
	const Syssegfree	: scno = 32
	const Syssegflush	: scno = 33
	const Sysrendezvous	: scno = 34
	const Sysunmount	: scno = 35
	const Sys_wait		: scno = 36
	const Syssemacquire	: scno = 37
	const Syssemrelease	: scno = 38
	const Sysseek		: scno = 39
	const Sysfversion	: scno = 40
	const Syserrstr		: scno = 41
	const Sysstat		: scno = 42
	const Sysfstat		: scno = 43
	const Syswstat		: scno = 44
	const Sysfwstat		: scno = 45
	const Sysmount		: scno = 46
	const Sysawait		: scno = 47
	const Syspread		: scno = 50
	const Syspwrite		: scno = 51
	const Systsemacquire	: scno = 52
	const Sys_nsec		: scno = 53


	const sysr1	: (-> int64)
	const bind	: (nm : byte[:], old : byte[:] -> int64)
	const chdir	: (dir : byte[:] -> int64)
	const close	: (fd : fd -> int64)
	const dup	: (old : fd, new : fd -> fd)
	const alarm	: (msec : uint32 -> int64)
	const exits	: (msg : byte[:] -> int64)
	const fauth	: (fd : fd, name : byte[:] -> int64)
	const segbrk	: (saddr : void#, addr : void# -> int64)
	const open	: (path : byte[:], opt : fdopt -> fd)
	const sleep	: (msec : uint32 -> int64)
	const rfork	: (rflags : rflags -> pid)
	const pipe	: (fds : fd[2]# -> int64)
	const create	: (path : byte[:], opt : fdopt, perm : int -> fd)
	const fd2path	: (fd : fd, path : byte[:] -> int64)
	const remove	: (path : byte[:] -> int64)
	const notify	: (fn : (a : void#, c : char# -> int64) -> int64)
	const noted	: (v : int32 -> int64)
	const segattach	: (attr : int32, class : byte[:], va : void#, len : uint32 -> int64)
	const segdetach	: (va : void# -> int64)
	const segfree	: (va : byte#, len : size -> int64)
	const segflush	: (va : void#, len : uint32 -> int64)
	const unmount	: (name : byte[:], old : byte[:] -> int64)
	const errstr	: (buf : byte[:] -> int64)
	const _errstr	: (buf : byte[:] -> int64)
	const stat	: (name : byte[:], edir : byte[:] -> int64)
	const fstat	: (fd : fd, edir : byte[:] -> int64)
	const wstat	: (name : byte[:], edir : byte[:] -> int64)
	const fwstat	: (fd : byte[:],  edir : byte[:] -> int64)
	const seek	: (fd : fd, len : off, ty : int64 -> off)
	const mount	: (fd : fd, afd : fd, old : byte[:], flag : int32, aname : byte[:] -> int64)
	const await	: (buf : byte[:] -> int64)
	const pread	: (fd : fd, buf : byte[:], off : off -> size)
	const pwrite	: (fd : fd, buf : byte[:], off : off -> size)
	const exec	: (bin : byte[:], args : byte[:][:] -> int64)
	const brk_	: (endp : byte# -> int64)
	const nsec	: (-> uint64)
	const semacquire	: (addr : uint32#, block : int -> int)
	const tsemacquire	: (addr : uint32#, ms : uint32 -> int)
	const semrelease	: (addr : uint32#, count : int32 -> int32)
	const rendezvous	: (tag : void#, val : void# -> void#)
	

	extern const alloca	: (sz : size	-> byte#)

	extern var tosptr	: tos#
	extern var curbrk	: byte#

	const atexit		: (fn : (-> void) -> void)

	pkglocal const __fini__	: (-> void)
;;

var exitfn : (-> void)[128]
var nexit : size

const atexit = {fn
	exitfn[nexit++] = fn
}

const __fini__ = {
	for var i = 0; i < nexit; i++
		exitfn[i]()
	;;
}

/* asm stub from syscall.s */
extern const syscall : (scno : scno, args : ... -> int64)
/* asm stubs from util+plan9.s */
extern const cstring	: (str : byte[:] -> byte#)


/*
ABI mismatch: Plan 9 aligns all arguments individually to
8 bytes, Myrddin uses natural alignment (min(sizeof(t), 16).
Cast to a 64 bit type to paper over this.
*/
generic a	= {a : @t;	-> (a : uint64)}
generic s	= {a : @t;	-> (a : int64)}
generic p	= {a : @t;	-> (a : byte#)}

const sysr1	= {;		-> syscall(Syssysr1)}
const bind	= {name, old;	-> syscall(Sysbind, cstring(name), cstring(old))}
const chdir 	= {dir;		-> syscall(Syschdir, cstring(dir)) }
const close 	= {fd;		-> syscall(Sysclose, a(fd))}
const dup	= {ofd, nfd;	-> (syscall(Sysdup, a(ofd), a(nfd)) : fd)}
const alarm 	= {msec;	-> syscall(Sysalarm, a(msec))}
const exits 	= {msg;		-> syscall(Sysexits, cstring(msg))}
const fauth 	= {fd, aname;	-> syscall(Sysfauth, a(fd), cstring(aname))}
const segbrk 	= {saddr, addr;	-> syscall(Syssegbrk, a(saddr), a(addr))}
const open 	= {path, opt;	-> (syscall(Sysopen, cstring(path), a(opt)) : fd)}
const sleep 	= {msec;	-> syscall(Syssleep, a(msec))}
const rfork 	= {rflags;	-> (syscall(Sysrfork, a(rflags)) : pid)}
const pipe 	= {fds;		-> syscall(Syspipe, a(fds))}
const create 	= {path, mode, perm;	-> (syscall(Syscreate, cstring(path), a(mode), a(perm)) : fd)}
const fd2path	= {fd, buf;	-> syscall(Sysfd2path, a(fd), p(buf), a(buf.len))}
const remove	= {path;	-> syscall(Sysremove, cstring(path))}
const notify	= {fn;		-> syscall(Sysnotify, fn)}	/* FIXME: this is likely to break when we do closures... */
const noted	= {v;		-> syscall(Sysnoted, a(v))}
const segattach	= {attr, class, va, len;	-> syscall(Syssegattach, a(attr), cstring(class), a(va), a(len))}
const segdetach	= {va;		-> syscall(Syssegdetach, a(va))}
const segfree	= {va, len;	-> syscall(Syssegfree, a(va), a(len))}
const segflush	= {va, len;	-> syscall(Syssegfree, a(va), a(len))}
const unmount	= {name, old;	-> syscall(Sysunmount, cstring(name), cstring(old))}
const _errstr	= {buf;		-> syscall(Syserrstr, p(buf), a(buf.len))}
const stat	= {name, edir;	-> syscall(Sysstat, cstring(name), p(edir), a(edir.len))}
const fstat	= {fd, edir;	-> syscall(Sysstat, a(fd), p(edir), a(edir.len))}
const wstat	= {name, edir;	-> syscall(Syswstat, cstring(name), p(edir), a(edir.len))}
const fwstat	= {fd, edir;	-> syscall(Sysfwstat, a(fd), p(edir), a(edir.len))}
const mount	= {fd, afd, old, flag, aname;	-> syscall(Sysmount, a(fd), a(afd), cstring(old), a(flag), cstring(aname))}
const pread	= {fd, buf, off;	-> (syscall(Syspread, a(fd), p(buf), a(buf.len), off) : size)}
const pwrite	= {fd, buf, off;	-> (syscall(Syspwrite, a(fd), p(buf), a(buf.len), s(off)) : size)}
const await	= {buf;	-> syscall(Sysawait, p(buf), a(buf.len))}
const brk_	= {endp;	-> syscall(Sysbrk_, p(endp))}
const nsec	= {;	-> (syscall(Sys_nsec) : uint64)}
const seek	= {fd, n, ty
	var ret : off
	syscall(Sysseek, a(&ret), a(fd), a(n), a(ty))
	-> ret
}

const exec	= {bin, args
	var p, cargs, i

	/* we need an array of C strings. */
	p = alloca((args.len + 1)*sizeof(byte#))
	cargs = (a(p) : byte##)[:args.len + 1]
	for i = 0; i < args.len; i++
		cargs[i] = cstring(args[i])
	;;
	cargs[args.len] = (0 : byte#)
	-> syscall(Sysexec, cstring(bin), a(cargs))
}

const errstr = {eb
	var tmp : byte[128]
	var n

	n = 128
	if eb.len < tmp.len
		n = eb.len
	;;
	_errstr(tmp[:])
	for var i = 0; i < n; i++
		eb[i] = tmp[i]
	;;
	_errstr(tmp[:])
	-> 0
}
	

/*const fversion	= {fd, bufsz, vers, nvers;	-> syscall(Sysfversion, fd, bufsz, }*/
const semacquire	= {addr, block; -> (syscall(Syssemacquire, a(addr), a(block)) : int)}
const tsemacquire	= {addr, ms; -> (syscall(Systsemacquire, a(addr), a(ms)) : int)}
const semrelease	= {addr, count; -> (syscall(Syssemrelease, a(addr), a(count)) : int32)}
const rendezvous	= {tag, val; -> (syscall(Sysrendezvous, a(tag), a(val)) : void#)}