Jacob Moody5e: support fauth(2)a20312f1 year agoHistory
711 lines · 12.7 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <thread.h>#include "dat.h"#include "fns.h"#include </sys/src/libc/9syscall/sys.h> static u32intarg(int n){	/* no locking necessary, since we're on the stack */	return *(u32int*) vaddrnol(P->R[13] + 4 + 4 * n, 4);} static u64intargv(int n){	return arg(n) | ((u64int)arg(n+1) << 32);} static voidsysopen(void){	u32int name, flags;	char *namet;	int fd, copied;		name = arg(0);	flags = arg(1);	namet = copyifnec(name, -1, &copied);	if(systrace)		fprint(2, "open(%#ux=\"%s\", %#o)\n", name, namet, flags);	fd = open(namet, flags);	if(copied)		free(namet);	if(fd < 0) {		noteerr(0, 1);		P->R[0] = fd;		return;	}	setcexec(P->fd, fd, flags & OCEXEC);	P->R[0] = fd;} static voidsyscreate(void){	u32int name, flags, perm;	char *namet;	int fd, copied;		name = arg(0);	flags = arg(1);	perm = arg(2);	namet = copyifnec(name, -1, &copied);	if(systrace)		fprint(2, "create(%#ux=\"%s\", %#o, %o)\n", name, namet, flags, perm);	fd = create(namet, flags, perm);	if(copied)		free(namet);	if(fd < 0) {		noteerr(0, 1);		P->R[0] = fd;		return;	}	setcexec(P->fd, fd, flags & OCEXEC);	P->R[0] = fd;} static voidsysclose(void){	u32int fd;		fd = arg(0);	if(systrace)		fprint(2, "close(%d)\n", fd);	P->R[0] = noteerr(close(fd), 0);	if((fd & (1<<31)) == 0)		setcexec(P->fd, fd, 0);} static voidsyspread(void){	int buffered;	u32int fd, size, buf;	u64int off;	void *targ;		fd = arg(0);	buf = arg(1);	size = arg(2);	off = argv(3);	if(systrace)		fprint(2, "pread(%d, %#ux, %ud, %#ullx)\n", fd, buf, size, off);	targ = bufifnec(buf, size, &buffered);	P->R[0] = noteerr(pread(fd, targ, size, off), size);	if(buffered)		copyback(buf, P->R[0], targ);} static voidsyspwrite(void){	u32int fd, size, buf;	u64int off;	int copied;	void *buft;		fd = arg(0);	buf = arg(1);	size = arg(2);	off = argv(3);	buft = copyifnec(buf, size, &copied);	if(systrace)		fprint(2, "pwrite(%d, %#ux, %ud, %#ullx)\n", fd, buf, size, off);	P->R[0] = noteerr(pwrite(fd, buft, size, off), size);	if(copied)		free(buft);} static voidsysseek(void){	u32int fd, type;	vlong n, *ret;	Segment *seg;		ret = vaddr(arg(0), 8, &seg);	fd = arg(1);	n = argv(2);	type = arg(4);	if(systrace)		fprint(2, "seek(%d, %lld, %d)\n", fd, n, type);	*ret = seek(fd, n, type);	if(*ret < 0) noteerr(0, 1);	segunlock(seg);} static voidsysfd2path(void){	u32int fd, buf, nbuf;	void *buft;	int buffered;		fd = arg(0);	buf = arg(1);	nbuf = arg(2);	buft = bufifnec(buf, nbuf, &buffered);	if(systrace)		fprint(2, "fd2path(%d, %#ux, %d)\n", fd, buf, nbuf);	P->R[0] = noteerr(fd2path(fd, buft, nbuf), 0);	if(buffered)		copyback(buf, nbuf, buft);} static voidsysstat(void){	u32int name, edir, nedir;	char *namet;	void *edirt;	int copied, buffered;		name = arg(0);	namet = copyifnec(name, -1, &copied);	edir = arg(1);	nedir = arg(2);	edirt = bufifnec(edir, nedir, &buffered);	if(systrace)		fprint(2, "stat(%#ux=\"%s\", %#ux, %ud)\n", name, namet, edir, nedir);	P->R[0] = noteerr(stat(namet, edirt, nedir), nedir);	if(copied)		free(namet);	if(buffered)		copyback(edir, P->R[0], edirt);} static voidsysfstat(void){	u32int fd, edir, nedir;	void *edirt;	int buffered;		fd = arg(0);	edir = arg(1);	nedir = arg(2);	edirt = bufifnec(edir, nedir, &buffered);	if(systrace)		fprint(2, "fstat(%d, %#ux, %d)\n", fd, edir, nedir);	P->R[0] = noteerr(fstat(fd, edirt, nedir), nedir);	if(buffered)		copyback(edir, P->R[0], edirt);} static voidsyswstat(void){	u32int name, edir, nedir;	char *namet;	void *edirt;	int copied, copied2;		name = arg(0);	namet = copyifnec(name, -1, &copied);	edir = arg(1);	nedir = arg(2);	edirt = copyifnec(edir, nedir, &copied2);	if(systrace)		fprint(2, "wstat(%#ux=\"%s\", %#ux, %ud)\n", name, namet, edir, nedir);	P->R[0] = noteerr(wstat(namet, edirt, nedir), nedir);	if(copied)		free(namet);	if(copied2)		free(edirt);} static voidsysfwstat(void){	u32int fd, edir, nedir;	void *edirt;	int copied;		fd = arg(0);	edir = arg(1);	nedir = arg(2);	edirt = copyifnec(edir, nedir, &copied);	if(systrace)		fprint(2, "fwstat(%d, %#ux, %d)\n", fd, edir, nedir);	P->R[0] = noteerr(fwstat(fd, edirt, nedir), nedir);	if(copied)		free(edirt);} static voidsysexits(void){	if(arg(0) == 0)		exits(nil);	else		exits(vaddrnol(arg(0), 0));} static voidsysbrk(void){	ulong v;	Segment *s;		v = arg(0);	if(systrace)		fprint(2, "brk(%#lux)\n", v);	v = v + 7 & -8;	if(v >= P->S[SEGSTACK]->start)		sysfatal("bss > stack, wtf?");	if(v < P->S[SEGBSS]->start)		sysfatal("bss length < 0, wtf?");	s = P->S[SEGBSS];	wlock(&s->rw);	s->dref = realloc(s->dref, v - s->start + sizeof(Ref));	if(s->dref == nil)		sysfatal("error reallocating");	s->data = s->dref + 1;	if(s->size < v - s->start)		memset((char*)s->data + s->size, 0, v - s->start - s->size);	s->size = v - s->start;	P->R[0] = 0;	wunlock(&s->rw);} static voidsyserrstr(void){	char buf[ERRMAX], *srct;	u32int src, len;	int copied;		src = arg(0);	len = arg(1);	srct = copyifnec(src, len, &copied);	strcpy(buf, P->errbuf);	utfecpy(P->errbuf, P->errbuf + ERRMAX, srct);	utfecpy(srct, srct + len, buf);	if(copied)		copyback(src, len, srct);	P->R[0] = 0;} static voidsyschdir(void){	u32int dir;	char *dirt;	int copied;		dir = arg(0);	dirt = copyifnec(dir, -1, &copied);	if(systrace)		fprint(2, "chdir(%#ux=\"%s\")\n", dir, dirt);	P->R[0] = noteerr(chdir(dirt), 0);	if(copied)		free(dirt);} static voidsysnotify(void){	u32int handler;		handler = arg(0);	if(systrace)		fprint(2, "notify(%#ux)\n", handler);	P->notehandler = handler;	P->R[0] = 0;} static voidsysnoted(void){	u32int v;		v = arg(0);	if(systrace)		fprint(2, "noted(%d)\n", v);	if(P->innote)		longjmp(P->notejmp, v + 1);	cherrstr("the front fell off");	P->R[0] = -1;} static voidsysrfork(void){	u32int flags;	int rc, i;	Process *p;	Segment *s, *t;	Fd *old;		flags = arg(0);	if(systrace)		fprint(2, "rfork(%#o)\n", flags);	if((flags & (RFFDG | RFCFDG)) == (RFFDG | RFCFDG) ||	   (flags & (RFNAMEG | RFCNAMEG)) == (RFNAMEG | RFCNAMEG) ||	   (flags & (RFENVG | RFCENVG)) == (RFENVG | RFCENVG)) {		P->R[0] = -1;		cherrstr("bad arg in syscall");		return;	}	if((flags & RFPROC) == 0) {		if(flags & RFFDG) {			old = P->fd;			P->fd = copyfd(P->fd);			fddecref(old);		}		if(flags & RFCFDG) {			old = P->fd;			P->fd = newfd();			fddecref(old);		}		P->R[0] = noteerr(rfork(flags), 0);		return;	}	incref(&nproc);	p = emallocz(sizeof(Process));	memcpy(p, P, sizeof(Process));	for(i = 0; i < SEGNUM; i++) {		s = p->S[i];		if(s == nil)			continue;		if((flags & RFMEM) == 0 && i != SEGTEXT || i == SEGSTACK) {			t = emallocz(sizeof(Segment));			incref(t);			t->size = s->size;			t->start = s->start;			t->dref = emalloc(sizeof(Ref) + s->size);			memset(t->dref, 0, sizeof(Ref));			incref(t->dref);			t->data = t->dref + 1;			memcpy(t->data, s->data, s->size);			p->S[i] = t;		} else {			incref(s->dref);			incref(s);		}	}		if(flags & RFFDG)		p->fd = copyfd(P->fd);	else if(flags & RFCFDG)		p->fd = newfd();	else		incref(P->fd); 	incref(P->path);	rc = rfork(RFMEM | flags);	if(rc < 0) /* this should NEVER happen */		sysfatal("rfork failed wtf: %r");	if(rc == 0) {		P = p;		atexit(cleanup);		P->pid = getpid();		inittos();		addproc(P);	}	P->R[0] = rc;} static voidsysexec(void){	u32int name, argv, *argvt;	char *namet, **argvv;	int i, argc, rc;	Segment *seg1, *seg2;		name = arg(0);	argv = arg(1);	namet = strdup(vaddr(name, 0, &seg1));	segunlock(seg1);	argvt = vaddr(argv, 0, &seg1);	if(systrace)		fprint(2, "exec(%#ux=\"%s\", %#ux)\n", name, namet, argv);	for(argc = 0; argvt[argc]; argc++)		;	argvv = emalloc(sizeof(char *) * argc);	for(i = 0; i < argc; i++) {		argvv[i] = strdup(vaddr(argvt[i], 0, &seg2));		segunlock(seg2);	}	segunlock(seg1);	rc = loadtext(namet, argc, argvv);	for(i = 0; i < argc; i++)		free(argvv[i]);	free(argvv);	if(rc < 0)		P->R[0] = noteerr(rc, 0);	free(namet);} static voidsysawait(void){	u32int s, n;	void *st;	int buffered;		s = arg(0);	n = arg(1);	st = bufifnec(s, n, &buffered);	if(systrace)		fprint(2, "await(%#ux, %d)\n", s, n);	P->R[0] = noteerr(await(st, n), 0);	if(buffered)		copyback(s, P->R[0], st);} static voidsyspipe(void){	u32int fd, *fdt;	int buffered;		fd = arg(0);	if(systrace)		fprint(2, "pipe(%#ux)\n", fd);	fdt = bufifnec(fd, 8, &buffered);	P->R[0] = noteerr(pipe((int *) fdt), 0);	if(buffered)		copyback(fd, 8, fdt);} static voidsysdup(void){	u32int oldfd, newfd;		oldfd = arg(0);	newfd = arg(1);	if(systrace)		fprint(2, "dup(%d, %d)\n", oldfd, newfd);	P->R[0] = noteerr(dup(oldfd, newfd), 0);} static voidsyssleep(void){	u32int n;		n = arg(0);	if(systrace)		fprint(2, "sleep(%d)\n", n);	P->R[0] = noteerr(sleep(n), 0);} static void

Lines 1–500 of 711.