shithub: mc

ref: a23019f08b895626d073258d5d20fa3479d73731
dir: /lib/sys/sys+openbsd-x64.myr/

View raw version
use "systypes.use"

pkg sys =
	type pid	= int32	/* process id */
	type scno	= int64	/*syscall*/
	type fdopt	= int64	/* fd options */
	type fd		= int32	/* fd */
	type whence	= uint64	/* seek from whence */
	type mprot	= int64	/* memory protection */
	type mopt	= int64	/* memory mapping options */
	type socktype	= int64	/* socket type */
	type sockproto	= int64	/* socket protocol */
	type sockopt	= int32	/* socket option */
	type sockfam	= uint8	/* socket family */
	type filemode	= uint32
	type filetype	= uint8
	type fcntlcmd	= int64
	type umtxop	= int32

	type clock = union
		`Clockrealtime
		`Clockmonotonic
		`Clockproccputime
		`Clockthreadcputime
		`Clockuptime
	;;

	type waitstatus = union
		`Waitfail int32
		`Waitexit int32
		`Waitsig  int32
		`Waitstop int32
	;;

	type timespec = struct
		sec	: uint64
		nsec	: uint64 
	;;

	type timeval = struct
		sec	: uint64
		usec	: uint64
	;;

	type rusage = struct
		utime	: timeval /* user time */
		stime	: timeval /* system time */
		maxrss	: uint64 /* max resident set size*/
		ixrss	: uint64 /* shared text size */
		idrss	: uint64 /* unshared data size */
		isrss	: uint64 /* unshared stack size */
		minflt	: uint64 /* page reclaims */
		majflt	: uint64 /* page faults */
		nswap	: uint64 /* swaps */
		inblock	: uint64 /* block input ops */
		oublock	: uint64 /* block output ops */
		msgsnd	: uint64 /* messages sent */	
		msgrcv	: uint64 /* messages received */
		nsignals : uint64 /* signals received */
		nvcsw	: uint64 /* voluntary context switches */
		nivcsw	: uint64 /* involuntary context switches */
	;;

	type tforkparams = struct
		tcb	: void#
		tid	: pid#
		stk	: byte#
	;;

	type statbuf = struct
		mode	: filemode
		dev	: uint32 
		ino	: uint64
		nlink	: uint32
		uid	: uint32
		gid	: uint32
		rdev	: uint32
		atime	: timespec
		mtime	: timespec
		ctime	: timespec
		size	: off
		blocks	: int64
		blksize	: uint32
		flags	: uint32
		gen	: uint32
		birthtim	: timespec 
	;;

	type utsname = struct
		system	: byte[32]
		node : byte[32] 
		release : byte[32]
		version : byte[32]
		machine : byte[32]
	;;

	type sockaddr = struct
		len	: byte
		fam	: sockfam
		data	: byte[14] /* what is the *actual* length? */
	;;

	type sockaddr_in = struct
		len	: byte
		fam	: sockfam
		port	: uint16
		addr	: byte[4]
		zero	: byte[8]
	;;

	type sockaddr_in6 = struct
		len	: byte
		fam	: sockfam
		port	: uint16
		flow	: uint32
		addr	: byte[16]
		scope	: uint32
	;;

	type sockaddr_un = struct
		len	: uint8
		fam	: sockfam
		path	: byte[104]
	;;

	type sockaddr_storage = struct
		len	: byte
		fam	: sockfam
		__pad1  : byte[6]
		__align : int64
		__pad2  : byte[240]
	;;	
	
	type dirent = struct
		fileno	: uint64
		off	: uint64
		reclen	: uint16
		ftype	: uint8
		namlen	: uint8
		__pad	: byte[4]
		name	: byte[256]	
	;;

	/* open options */
	const Ordonly  	: fdopt = 0x0
	const Owronly  	: fdopt = 0x1
	const Ordwr    	: fdopt = 0x2
	const Oappend  	: fdopt = 0x8
	const Ocreat   	: fdopt = 0x200
	const Onofollow	: fdopt = 0x100
	const Ondelay  	: fdopt = 0x4
	const Otrunc   	: fdopt = 0x400
	const Odir	: fdopt = 0x20000

        /* stat modes */	
	const Sifmt	: filemode = 0xf000
	const Sififo	: filemode = 0x1000
	const Sifchr	: filemode = 0x2000
	const Sifdir	: filemode = 0x4000
	const Sifblk	: filemode = 0x6000
	const Sifreg	: filemode = 0x8000
	const Siflnk	: filemode = 0xa000
	const Sifsock 	: filemode = 0xc000
	const Sisvtx 	: filemode = 0x0200

	/* mmap protection */
	const Mprotnone	: mprot = 0x0
	const Mprotrd	: mprot = 0x1
	const Mprotwr	: mprot = 0x2
	const Mprotexec	: mprot = 0x4
	const Mprotrw	: mprot = 0x3

	/* mmap options */
	const Mshared	: mopt = 0x1
	const Mpriv	: mopt = 0x2
	const Mfixed	: mopt = 0x10
	const Mfile	: mopt = 0x0
	const Manon	: mopt = 0x1000
	const Mnoreplace	: mopt = 0x0800

	/* file types */
	const Dtunknown	: filetype = 0
	const Dtfifo	: filetype = 1
	const Dtchr	: filetype = 2
	const Dtdir	: filetype = 4
	const Dtblk	: filetype = 6
	const Dtreg	: filetype = 8
	const Dtlnk	: filetype = 10
	const Dtsock	: filetype = 12

	/* socket families. INCOMPLETE. */
	const Afunspec	: sockfam = 0
	const Afunix	: sockfam = 1
	const Afinet	: sockfam = 2
	const Afinet6	: sockfam = 24

	/* socket types. */
	const Sockstream	: socktype = 1
	const Sockdgram		: socktype = 2
	const Sockraw		: socktype = 3
	const Sockrdm		: socktype = 4
	const Sockseqpacket	: socktype = 5
	const Solsock	: socktype =	0xffff

	const Sodebug		: sockopt = 0x0001	/* turn on debugging info recording */
	const Soacceptconn	: sockopt = 0x0002	/* socket has had listen() */
	const Soreuseaddr	: sockopt = 0x0004	/* allow local address reuse */
	const Sokeepalive	: sockopt = 0x0008	/* keep connections alive */
	const Sodontroute	: sockopt = 0x0010	/* just use interface addresses */
	const Sobroadcast	: sockopt = 0x0020	/* permit sending of broadcast msgs */
	const Souseloopback	: sockopt = 0x0040	/* bypass hardware when possible */
	const Solinger		: sockopt = 0x0080	/* linger on close if data present */
	const Sooobinline	: sockopt = 0x0100	/* leave received OOB data in line */
	const Soreuseport	: sockopt = 0x0200	/* allow local address & port reuse */
	const Sotimestamp	: sockopt = 0x0800	/* timestamp received dgram traffic */
	const Sobindany		: sockopt = 0x1000	/* allow bind to any address */
	const Sosndbuf		: sockopt = 0x1001	/* send buffer size */
	const Sorcvbuf		: sockopt = 0x1002	/* receive buffer size */
	const Sosndlowat	: sockopt = 0x1003	/* send low-water mark */
	const Sorcvlowat	: sockopt = 0x1004	/* receive low-water mark */
	const Sosndtimeo	: sockopt = 0x1005	/* send timeout */
	const Sorcvtimeo	: sockopt = 0x1006	/* receive timeout */
	const Soerror		: sockopt = 0x1007	/* get error status and clear */
	const Sotype		: sockopt = 0x1008	/* get socket type */
	const Sonetproc		: sockopt = 0x1020	/* multiplex; network processing */
	const Sortable		: sockopt = 0x1021	/* routing table to be used */
	const Sopeercred	: sockopt = 0x1022	/* get connect-time credentials */
	const Sosplice		: sockopt = 0x1023	/* splice data to other socket */

	/* network protocols */
	const Ipproto_ip	: sockproto = 0
	const Ipproto_icmp	: sockproto = 1
	const Ipproto_tcp	: sockproto = 6
	const Ipproto_udp	: sockproto = 17
	const Ipproto_raw	: sockproto = 255

	const Seekset	: whence = 0
	const Seekcur	: whence = 1
	const Seekend	: whence = 2

	/* system specific constants */
	const Maxpathlen	: size = 1024

	/* fcntl constants */
	const Fdupfd	 : fcntlcmd = 0		/* duplicate file descriptor */
	const Fgetfd	 : fcntlcmd = 1		/* get file descriptor flags */
	const Fsetfd	 : fcntlcmd = 2		/* set file descriptor flags */
	const Fgetfl	 : fcntlcmd = 3		/* get file status flags */
	const Fsetfl	 : fcntlcmd = 4		/* set file status flags */
	const Fgetown	 : fcntlcmd = 5		/* get SIGIO/SIGURG proc/pgrp */
	const Fsetown	 : fcntlcmd = 6		/* set SIGIO/SIGURG proc/pgrp */
	const Fogetlk	 : fcntlcmd = 7		/* get record locking information */
	const Fosetlk	 : fcntlcmd = 8		/* set record locking information */

	/* return value for a failed mapping */
	const Mapbad	: byte# = (-1 : byte#)

	/* syscalls */
	const Syssyscall : scno = 0
	const Sysexit : scno = 1
	const Sysfork : scno = 2
	const Sysread : scno = 3
	const Syswrite : scno = 4
	const Sysopen : scno = 5
	const Sysclose : scno = 6
	const Sysgetentropy : scno = 7
	const Sys__tfork : scno = 8
	const Syslink : scno = 9
	const Sysunlink : scno = 10
	const Syswait4 : scno = 11
	const Syschdir : scno = 12
	const Sysfchdir : scno = 13
	const Sysmknod : scno = 14
	const Syschmod : scno = 15
	const Syschown : scno = 16
	const Sysbreak : scno = 17
	const Sysgetdtablecount : scno = 18
	const Sysgetrusage : scno = 19
	const Sysgetpid : scno = 20
	const Sysmount : scno = 21
	const Sysunmount : scno = 22
	const Syssetuid : scno = 23
	const Sysgetuid : scno = 24
	const Sysgeteuid : scno = 25
	const Sysptrace : scno = 26
	const Sysrecvmsg : scno = 27
	const Syssendmsg : scno = 28
	const Sysrecvfrom : scno = 29
	const Sysaccept : scno = 30
	const Sysgetpeername : scno = 31
	const Sysgetsockname : scno = 32
	const Sysaccess : scno = 33
	const Syschflags : scno = 34
	const Sysfchflags : scno = 35
	const Syssync : scno = 36
	const Syskill : scno = 37
	const Sysstat : scno = 38
	const Sysgetppid : scno = 39
	const Syslstat : scno = 40
	const Sysdup : scno = 41
	const Sysfstatat : scno = 42
	const Sysgetegid : scno = 43
	const Sysprofil : scno = 44
	const Sysktrace : scno = 45
	const Syssigaction : scno = 46
	const Sysgetgid : scno = 47
	const Syssigprocmask : scno = 48
	const Sysgetlogin : scno = 49
	const Syssetlogin : scno = 50
	const Sysacct : scno = 51
	const Syssigpending : scno = 52
	const Sysfstat : scno = 53
	const Sysioctl : scno = 54
	const Sysreboot : scno = 55
	const Sysrevoke : scno = 56
	const Syssymlink : scno = 57
	const Sysreadlink : scno = 58
	const Sysexecve : scno = 59
	const Sysumask : scno = 60
	const Syschroot : scno = 61
	const Sysgetfsstat : scno = 62
	const Sysstatfs : scno = 63
	const Sysfstatfs : scno = 64
	const Sysfhstatfs : scno = 65
	const Sysvfork : scno = 66
	const Sysgettimeofday : scno = 67
	const Syssettimeofday : scno = 68
	const Syssetitimer : scno = 69
	const Sysgetitimer : scno = 70
	const Sysselect : scno = 71
	const Syskevent : scno = 72
	const Sysmunmap : scno = 73
	const Sysmprotect : scno = 74
	const Sysmadvise : scno = 75
	const Sysutimes : scno = 76
	const Sysfutimes : scno = 77
	const Sysmincore : scno = 78
	const Sysgetgroups : scno = 79
	const Syssetgroups : scno = 80
	const Sysgetpgrp : scno = 81
	const Syssetpgid : scno = 82
	const Syssendsyslog : scno = 83
	const Sysutimensat : scno = 84
	const Sysfutimens : scno = 85
	const Syskbind : scno = 86
	const Sysclock_gettime : scno = 87
	const Sysclock_settime : scno = 88
	const Sysclock_getres : scno = 89
	const Sysdup2 : scno = 90
	const Sysnanosleep : scno = 91
	const Sysfcntl : scno = 92
	const Sysaccept4 : scno = 93
	const Sys__thrsleep : scno = 94
	const Sysfsync : scno = 95
	const Syssetpriority : scno = 96
	const Syssocket : scno = 97
	const Sysconnect : scno = 98
	const Sysgetdents : scno = 99
	const Sysgetpriority : scno = 100
	const Syspipe2 : scno = 101
	const Sysdup3 : scno = 102
	const Syssigreturn : scno = 103
	const Sysbind : scno = 104
	const Syssetsockopt : scno = 105
	const Syslisten : scno = 106
	const Syschflagsat : scno = 107
	const Systame : scno = 108
	const Sysppoll : scno = 109
	const Syspselect : scno = 110
	const Syssigsuspend : scno = 111
	const Sysgetsockopt : scno = 118
	const Sysreadv : scno = 120
	const Syswritev : scno = 121
	const Sysfchown : scno = 123
	const Sysfchmod : scno = 124
	const Syssetreuid : scno = 126
	const Syssetregid : scno = 127
	const Sysrename : scno = 128
	const Sysflock : scno = 131
	const Sysmkfifo : scno = 132
	const Syssendto : scno = 133
	const Sysshutdown : scno = 134
	const Syssocketpair : scno = 135
	const Sysmkdir : scno = 136
	const Sysrmdir : scno = 137
	const Sysadjtime : scno = 140
	const Syssetsid : scno = 147
	const Sysquotactl : scno = 148
	const Sysnfssvc : scno = 155
	const Sysgetfh : scno = 161
	const Syssysarch : scno = 165
	const Syspread : scno = 173
	const Syspwrite : scno = 174
	const Syssetgid : scno = 181
	const Syssetegid : scno = 182
	const Sysseteuid : scno = 183
	const Syspathconf : scno = 191
	const Sysfpathconf : scno = 192
	const Sysswapctl : scno = 193
	const Sysgetrlimit : scno = 194
	const Syssetrlimit : scno = 195
	const Sysmmap : scno = 197
	const Sys__syscall : scno = 198
	const Syslseek : scno = 199
	const Systruncate : scno = 200
	const Sysftruncate : scno = 201
	const Sys__sysctl : scno = 202
	const Sysmlock : scno = 203
	const Sysmunlock : scno = 204
	const Sysgetpgid : scno = 207
	const Sysutrace : scno = 209
	const Syssemget : scno = 221
	const Sysmsgget : scno = 225
	const Sysmsgsnd : scno = 226
	const Sysmsgrcv : scno = 227
	const Sysshmat : scno = 228
	const Sysshmdt : scno = 230
	const Sysminherit : scno = 250
	const Syspoll : scno = 252
	const Sysissetugid : scno = 253
	const Syslchown : scno = 254
	const Sysgetsid : scno = 255
	const Sysmsync : scno = 256
	const Syspipe : scno = 263
	const Sysfhopen : scno = 264
	const Syspreadv : scno = 267
	const Syspwritev : scno = 268
	const Syskqueue : scno = 269
	const Sysmlockall : scno = 271
	const Sysmunlockall : scno = 272
	const Sysgetresuid : scno = 281
	const Syssetresuid : scno = 282
	const Sysgetresgid : scno = 283
	const Syssetresgid : scno = 284
	const Sysmquery : scno = 286
	const Sysclosefrom : scno = 287
	const Syssigaltstack : scno = 288
	const Sysshmget : scno = 289
	const Syssemop : scno = 290
	const Sysfhstat : scno = 294
	const Sys__semctl : scno = 295
	const Sysshmctl : scno = 296
	const Sysmsgctl : scno = 297
	const Syssched_yield : scno = 298
	const Sysgetthrid : scno = 299
	const Sys__thrwakeup : scno = 301
	const Sys__threxit : scno = 302
	const Sys__thrsigdivert : scno = 303
	const Sys__getcwd : scno = 304
	const Sysadjfreq : scno = 305
	const Syssetrtable : scno = 310
	const Sysgetrtable : scno = 311
	const Sysfaccessat : scno = 313
	const Sysfchmodat : scno = 314
	const Sysfchownat : scno = 315
	const Syslinkat : scno = 317
	const Sysmkdirat : scno = 318
	const Sysmkfifoat : scno = 319
	const Sysmknodat : scno = 320
	const Sysopenat : scno = 321
	const Sysreadlinkat : scno = 322
	const Sysrenameat : scno = 323
	const Syssymlinkat : scno = 324
	const Sysunlinkat : scno = 325
	const Sys__set_tcb : scno = 329
	const Sys__get_tcb : scno = 330

	extern const syscall : (sc:scno, args:... -> int64)

	/* process control */
	const exit	: (status:int -> void)
	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)
	/* wrappers to extract wait status */
	const waitstatus	: (st : int32 -> waitstatus)
	extern const __tfork_thread	: (tfp : tforkparams#, sz : size, fn : void#, arg : void# -> pid)

	/* fd manipulation */
	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 unlink	: (path:byte[:] -> int)
	const read	: (fd:fd, buf:byte[:] -> size)
	const write	: (fd:fd, buf:byte[:] -> size)
	const lseek	: (fd:fd, off : off, whence : whence -> int64)
	const stat	: (path:byte[:], sb:statbuf# -> int64)
	const lstat	: (path:byte[:], sb:statbuf# -> int64)
	const fstat	: (fd:fd, sb:statbuf# -> int64)
	const mkdir	: (path : byte[:], mode : int64	-> int64)
	generic ioctl	: (fd:fd, req : int64, arg:@a# -> int64)
	const getdents	: (fd : fd, buf : byte[:] -> int64)
	const chdir	: (p : byte[:] -> int64)
	const __getcwd	: (buf : byte[:] -> int64)

	/* fd stuff */
	const pipe	: (fds : fd[2]# -> int64)
	const dup	: (fd : fd -> fd)
	const dup2	: (src : fd, dst : fd -> fd)
	/* NB: the C ABI uses '...' for the args. */
	const fcntl	: (fd : fd, cmd : fcntlcmd, args : byte# -> int64)

	/* networking */
	const socket	: (dom : sockfam, stype : socktype, proto : sockproto	-> fd)
	const connect	: (sock	: fd, addr : sockaddr#, len : size -> int)
	const accept	: (sock : fd, addr : sockaddr#, len : size# -> fd)
	const listen	: (sock : fd, backlog : int	-> int)
	const bind	: (sock : fd, addr : sockaddr#, len : size -> int)
	const setsockopt	: (sock : fd, lev : socktype, opt : sockopt, val : void#, len : size -> int)
	const getsockopt	: (sock : fd, lev : socktype, opt : sockopt, val : void#, len : size# -> int)

	/* memory mapping */
	const munmap	: (addr:byte#, len:size -> int64)
	const mmap	: (addr:byte#, len:size, prot:mprot, flags:mopt, fd:fd, off:off -> byte#)

	/* time - doublecheck if this is right */
	const clock_getres	: (clk : clock, ts : timespec# -> int32)
	const clock_gettime	: (clk : clock, ts : timespec# -> int32)
	const clock_settime	: (clk : clock, ts : timespec# -> int32)
	const sleep	: (time : uint64 -> int32)
	const nanosleep	: (req : timespec#, rem : timespec# -> int32)

	/* system information */
	const uname 	: (buf : utsname# -> int)
	const sysctl	: (mib : int[:], old : byte[:]#, new : byte[:] -> int)

	/* filled by start code */
	extern const __cenvp : byte##
	extern const __environment : byte[:][:]
;;

/* 
wraps a syscall argument, converting it to 64 bits for the syscall function. This is
the same as casting, but more concise than writing a cast to uint64
*/
generic a = {x : @t; -> (x : uint64)}

extern const cstring	: (str : byte[:] -> byte#)
extern const alloca	: (sz : size	-> byte#)

extern const __freebsd_pipe	: (fds : fd[2]# -> int64)

/* process management */
const exit	= {status;		syscall(Sysexit, a(status))}
const getpid	= {;			-> (syscall(Sysgetpid, 1) : pid)}
const kill	= {pid, sig;		-> syscall(Syskill, pid, sig)}
const fork	= {;			-> (syscall(Sysfork) : pid)}
const wait4	= {pid, loc, opt, usage;	-> syscall(Syswait4, pid, loc, opt, usage)}
const waitpid	= {pid, loc, opt;
	-> wait4(pid, loc, opt, (0 : rusage#)) 
}

const execv	= {cmd, args
	var p, cargs, i

	/* of course we fucking have to duplicate this code everywhere,
	* since we want to stack allocate... */
	p = alloca((args.len + 1)*sizeof(byte#))
	cargs = (p : byte##)[:args.len + 1]
	for i = 0; i < args.len; i++
		cargs[i] = cstring(args[i])
	;;
	cargs[args.len] = (0 : byte#)
	-> syscall(Sysexecve, cstring(cmd), a(p), a(__cenvp))
}

const execve	= {cmd, args, env
	var cargs, cenv, i
	var p

	/* copy the args */
	p = alloca((args.len + 1)*sizeof(byte#))
	cargs = (p : byte##)[:args.len]
	for i = 0; i < args.len; i++
		cargs[i] = cstring(args[i])
	;;
	cargs[args.len] = (0 : byte#)

	/*
	 copy the env.
	 of course we fucking have to duplicate this code everywhere,
	 since we want to stack allocate... 
	*/
	p = alloca((env.len + 1)*sizeof(byte#))
	cenv = (p : byte##)[:env.len]
	for i = 0; i < env.len; i++
		cenv[i] = cstring(env[i])
	;;
	cenv[env.len] = (0 : byte#)

	-> syscall(Sysexecve, cstring(cmd), a(p), a(cenv))
}

/* fd manipulation */
const open	= {path, opts;		-> (syscall(Sysopen, cstring(path), a(opts), a(0o777)) : fd)}
const openmode	= {path, opts, mode;	-> (syscall(Sysopen, cstring(path), a(opts), a(mode)) : fd)}
const close	= {fd;			-> syscall(Sysclose, a(fd))}
const creat	= {path, mode;		-> (openmode(path, Ocreat | Otrunc | Owronly, mode) : fd)}
const unlink	= {path;		-> (syscall(Sysunlink, cstring(path)) : int)}
const read	= {fd, buf;		-> (syscall(Sysread, a(fd), (buf : byte#), a(buf.len)) : size)}
const write	= {fd, buf;		-> (syscall(Syswrite, a(fd), (buf : byte#), a(buf.len)) : size)}
const lseek	= {fd, off, whence;	-> syscall(Syslseek, a(fd), a(off), a(whence))}
const stat	= {path, sb;		-> syscall(Sysstat, cstring(path), a(sb))}
const lstat	= {path, sb;		-> syscall(Syslstat, cstring(path), a(sb))}
const fstat	= {fd, sb;		-> syscall(Sysfstat, a(fd), a(sb))}
const mkdir	= {path, mode;		-> (syscall(Sysmkdir, cstring(path), a(mode)) : int64)}
generic ioctl	= {fd, req, arg;	-> (syscall(Sysioctl, a(fd), a(req), a(arg)) : int64)}
const chdir	= {dir;	-> syscall(Syschdir, cstring(dir))}
const __getcwd	= {buf;	-> syscall(Sys__getcwd, a(buf), a(buf.len))}
const getdents	= {fd, buf;		-> (syscall(Sysgetdents, a(buf), a(buf.len)) : int64)}

/* file stuff */
const pipe	= {fds;	-> syscall(Syspipe, fds)}
const dup 	= {fd;	-> (syscall(Sysdup, a(fd)) : fd)}
const dup2 	= {src, dst;	-> (syscall(Sysdup2, a(src), a(dst)) : fd)}
const fcntl	= {fd, cmd, args; 	-> syscall(Sysfcntl, a(fd), a(cmd), a(args))}

/* networking */
const socket	= {dom, stype, proto;	-> (syscall(Syssocket, a(dom), a(stype), a(proto)) : fd)}
const connect	= {sock, addr, len;	-> (syscall(Sysconnect, a(sock), a(addr), a(len)) : int)}
const accept	= {sock, addr, len;	-> (syscall(Sysaccept, a(sock), a(addr), a(len)) : fd)}
const listen	= {sock, backlog;	-> (syscall(Syslisten, a(sock), a(backlog)) : int)}
const bind	= {sock, addr, len;	-> (syscall(Sysbind, a(sock), a(addr), a(len)) : int)}
const setsockopt	= {sock, lev, opt, val, len;	-> (syscall(Syssetsockopt, a(sock), a(lev), a(opt), a(val), a(len)) : int)}
const getsockopt	= {sock, lev, opt, val, len;	-> (syscall(Syssetsockopt, a(sock), a(lev), a(opt), a(val), a(len)) : int)}

/* memory management */
const munmap	= {addr, len;		-> syscall(Sysmunmap, a(addr), a(len))}
const mmap	= {addr, len, prot, flags, fd, off;
	/* the actual syscall has padding on the offset arg */
	-> (syscall(Sysmmap, a(addr), a(len), a(prot), a(flags), a(fd), a(0), a(off)) : byte#)
}

/* time */
const clock_getres = {clk, ts;	-> (syscall(Sysclock_getres, clockid(clk), a(ts)) : int32)}
const clock_gettime = {clk, ts;	-> (syscall(Sysclock_gettime, clockid(clk), a(ts)) : int32)}
const clock_settime = {clk, ts;	-> (syscall(Sysclock_settime, clockid(clk), a(ts)) : int32)}

const sleep = {time
	var req, rem
	req = [.sec = time, .nsec = 0]
	-> nanosleep(&req, &rem)
}

const nanosleep	= {req, rem;	-> (syscall(Sysnanosleep, a(req), a(rem)) : int32)}


/* system information */
const uname	= {buf
	var mib : int[2]
	var ret
	var sys
	var nod
	var rel
	var ver
	var mach

	ret = 0
	mib[0] = 1 /* CTL_KERN */
	mib[1] = 1 /* KERN_OSTYPE */
	sys = buf.system[:]
	ret = sysctl(mib[:], &sys, [][:])
	if ret < 0
		-> ret
	;;

	mib[0] = 1 /* CTL_KERN */
	mib[1] = 10 /* KERN_HOSTNAME */
	nod = buf.node[:]
	ret = sysctl(mib[:], &nod, [][:])
	if ret < 0
		-> ret
	;;

	mib[0] = 1 /* CTL_KERN */
	mib[1] = 2 /* KERN_OSRELEASE */
	rel = buf.release[:]
	ret = sysctl(mib[:], &rel, [][:])
	if ret < 0
		-> ret
	;;

	mib[0] = 1 /* CTL_KERN */
	mib[1] = 27 /* KERN_OSVERSION */
	ver = buf.version[:]
	ret = sysctl(mib[:], &ver, [][:])
	if ret < 0
		-> ret
	;;

	mib[0] = 6 /* CTL_HW */
	mib[1] = 1 /* HW_MACHINE */
	mach = buf.machine[:]
	ret = sysctl(mib[:], &mach, [][:])
	if ret < 0
		-> ret
	;;

	-> 0
}

const sysctl = {mib, old, new
	var mibp
	var mibsz
	var o
	var oldp
	var oldsz
	var newp
	var newsz
	var ret

	mibp = (mib : byte#)
	mibsz = a(mib.len)
	o = old#
	oldp = (o : byte#)
	oldsz = (o.len : int64)
	newp = (new : byte#)
	newsz = a(new.len)

	/* all args already passed through a() or ar  ptrs */
	ret = (syscall(Sys__sysctl, mibp, mibsz, oldp, a(&oldsz), newp, newsz) : int)

	old# = o[:oldsz]
	-> ret
}

const clockid = {clk
	match clk
	| `Clockrealtime:	-> 0
	| `Clockproccputime:	-> 2
	| `Clockmonotonic:	-> 3
	| `Clockthreadcputime:	-> 4
	| `Clockuptime:	-> 5
	;;
	-> -1
}

const waitstatus = {st
	if st < 0
		-> `Waitfail st
	;;
	match st & 0o177
	| 0:    -> `Waitexit (st >> 8)
	| 0x7f:-> `Waitstop (st >> 8)
	| sig:  -> `Waitsig sig
	;;
}