xref: /plan9/sys/src/cmd/vnc/compat.c (revision 74f16c8187aab477889167f2422d0597b1b7d0ff)
19a747e4fSDavid du Colombier #include	<u.h>
29a747e4fSDavid du Colombier #include	<libc.h>
39a747e4fSDavid du Colombier #include	"compat.h"
49a747e4fSDavid du Colombier #include	"error.h"
59a747e4fSDavid du Colombier 
69a747e4fSDavid du Colombier #include	"errstr.h"
79a747e4fSDavid du Colombier 
89a747e4fSDavid du Colombier ulong	kerndate;
99a747e4fSDavid du Colombier Proc	**privup;
109a747e4fSDavid du Colombier char	*eve;
119a747e4fSDavid du Colombier extern void *mainmem;
129a747e4fSDavid du Colombier 
139a747e4fSDavid du Colombier void
_assert(char * fmt)149a747e4fSDavid du Colombier _assert(char *fmt)
159a747e4fSDavid du Colombier {
169a747e4fSDavid du Colombier 	panic("assert failed: %s", fmt);
179a747e4fSDavid du Colombier }
189a747e4fSDavid du Colombier 
199a747e4fSDavid du Colombier int
errdepth(int ed)209a747e4fSDavid du Colombier errdepth(int ed)
219a747e4fSDavid du Colombier {
229a747e4fSDavid du Colombier 	if(ed >= 0 && up->nerrlab != ed)
239a747e4fSDavid du Colombier 		panic("unbalanced error depth: expected %d got %d\n", ed, up->nerrlab);
249a747e4fSDavid du Colombier 	return up->nerrlab;
259a747e4fSDavid du Colombier }
269a747e4fSDavid du Colombier 
279a747e4fSDavid du Colombier void
newup(char * name)289a747e4fSDavid du Colombier newup(char *name)
299a747e4fSDavid du Colombier {
309a747e4fSDavid du Colombier 	up = smalloc(sizeof(Proc));
319a747e4fSDavid du Colombier 	up->user = eve;
329a747e4fSDavid du Colombier 	strncpy(up->name, name, KNAMELEN-1);
339a747e4fSDavid du Colombier 	up->name[KNAMELEN-1] = '\0';
349a747e4fSDavid du Colombier }
359a747e4fSDavid du Colombier 
369a747e4fSDavid du Colombier void
kproc(char * name,void (* f)(void *),void * a)379a747e4fSDavid du Colombier kproc(char *name, void (*f)(void *), void *a)
389a747e4fSDavid du Colombier {
399a747e4fSDavid du Colombier 	int pid;
409a747e4fSDavid du Colombier 
419a747e4fSDavid du Colombier 	pid = rfork(RFPROC|RFMEM|RFNOWAIT);
429a747e4fSDavid du Colombier 	switch(pid){
439a747e4fSDavid du Colombier 	case -1:
449a747e4fSDavid du Colombier 		panic("can't make new thread: %r");
459a747e4fSDavid du Colombier 	case 0:
469a747e4fSDavid du Colombier 		break;
479a747e4fSDavid du Colombier 	default:
489a747e4fSDavid du Colombier 		return;
499a747e4fSDavid du Colombier 	}
509a747e4fSDavid du Colombier 
519a747e4fSDavid du Colombier 	newup(name);
529a747e4fSDavid du Colombier 	if(!waserror())
539a747e4fSDavid du Colombier 		(*f)(a);
549a747e4fSDavid du Colombier 	_exits(nil);
559a747e4fSDavid du Colombier }
569a747e4fSDavid du Colombier 
579a747e4fSDavid du Colombier void
kexit(void)589a747e4fSDavid du Colombier kexit(void)
599a747e4fSDavid du Colombier {
609a747e4fSDavid du Colombier 	_exits(nil);
619a747e4fSDavid du Colombier }
629a747e4fSDavid du Colombier 
639a747e4fSDavid du Colombier void
initcompat(void)649a747e4fSDavid du Colombier initcompat(void)
659a747e4fSDavid du Colombier {
669a747e4fSDavid du Colombier 	rfork(RFREND);
679a747e4fSDavid du Colombier 	privup = privalloc();
689a747e4fSDavid du Colombier 	kerndate = seconds();
699a747e4fSDavid du Colombier 	eve = getuser();
709a747e4fSDavid du Colombier 	newup("main");
719a747e4fSDavid du Colombier }
729a747e4fSDavid du Colombier 
739a747e4fSDavid du Colombier int
openmode(ulong o)749a747e4fSDavid du Colombier openmode(ulong o)
759a747e4fSDavid du Colombier {
769a747e4fSDavid du Colombier 	o &= ~(OTRUNC|OCEXEC|ORCLOSE);
779a747e4fSDavid du Colombier 	if(o > OEXEC)
789a747e4fSDavid du Colombier 		error(Ebadarg);
799a747e4fSDavid du Colombier 	if(o == OEXEC)
809a747e4fSDavid du Colombier 		return OREAD;
819a747e4fSDavid du Colombier 	return o;
829a747e4fSDavid du Colombier }
839a747e4fSDavid du Colombier 
849a747e4fSDavid du Colombier void
panic(char * fmt,...)859a747e4fSDavid du Colombier panic(char *fmt, ...)
869a747e4fSDavid du Colombier {
879a747e4fSDavid du Colombier 	char buf[512];
889a747e4fSDavid du Colombier 	char buf2[512];
899a747e4fSDavid du Colombier 	va_list va;
909a747e4fSDavid du Colombier 
919a747e4fSDavid du Colombier 	va_start(va, fmt);
929a747e4fSDavid du Colombier 	vseprint(buf, buf+sizeof(buf), fmt, va);
939a747e4fSDavid du Colombier 	va_end(va);
949a747e4fSDavid du Colombier 	sprint(buf2, "panic: %s\n", buf);
959a747e4fSDavid du Colombier 	write(2, buf2, strlen(buf2));
969a747e4fSDavid du Colombier 
979a747e4fSDavid du Colombier 	exits("error");
989a747e4fSDavid du Colombier }
999a747e4fSDavid du Colombier 
1009a747e4fSDavid du Colombier void*
smalloc(ulong n)1019a747e4fSDavid du Colombier smalloc(ulong n)
1029a747e4fSDavid du Colombier {
1039a747e4fSDavid du Colombier 	void *p;
1049a747e4fSDavid du Colombier 
1059a747e4fSDavid du Colombier 	p = mallocz(n, 1);
1069a747e4fSDavid du Colombier 	if(p == nil)
1079a747e4fSDavid du Colombier 		panic("out of memory");
1089a747e4fSDavid du Colombier 	setmalloctag(p, getcallerpc(&n));
1099a747e4fSDavid du Colombier 	return p;
1109a747e4fSDavid du Colombier }
1119a747e4fSDavid du Colombier 
1129a747e4fSDavid du Colombier long
seconds(void)1139a747e4fSDavid du Colombier seconds(void)
1149a747e4fSDavid du Colombier {
1159a747e4fSDavid du Colombier 	return time(nil);
1169a747e4fSDavid du Colombier }
1179a747e4fSDavid du Colombier 
1189a747e4fSDavid du Colombier void
error(char * err)1199a747e4fSDavid du Colombier error(char *err)
1209a747e4fSDavid du Colombier {
1219a747e4fSDavid du Colombier 	strncpy(up->error, err, ERRMAX);
1229a747e4fSDavid du Colombier 	nexterror();
1239a747e4fSDavid du Colombier }
1249a747e4fSDavid du Colombier 
1259a747e4fSDavid du Colombier void
nexterror(void)1269a747e4fSDavid du Colombier nexterror(void)
1279a747e4fSDavid du Colombier {
1289a747e4fSDavid du Colombier 	longjmp(up->errlab[--up->nerrlab], 1);
1299a747e4fSDavid du Colombier }
1309a747e4fSDavid du Colombier 
1319a747e4fSDavid du Colombier int
readstr(ulong off,char * buf,ulong n,char * str)1329a747e4fSDavid du Colombier readstr(ulong off, char *buf, ulong n, char *str)
1339a747e4fSDavid du Colombier {
1349a747e4fSDavid du Colombier 	int size;
1359a747e4fSDavid du Colombier 
1369a747e4fSDavid du Colombier 	size = strlen(str);
1379a747e4fSDavid du Colombier 	if(off >= size)
1389a747e4fSDavid du Colombier 		return 0;
1399a747e4fSDavid du Colombier 	if(off+n > size)
1409a747e4fSDavid du Colombier 		n = size-off;
1419a747e4fSDavid du Colombier 	memmove(buf, str+off, n);
1429a747e4fSDavid du Colombier 	return n;
1439a747e4fSDavid du Colombier }
1449a747e4fSDavid du Colombier 
1459a747e4fSDavid du Colombier void
_rendsleep(void * tag)146*74f16c81SDavid du Colombier _rendsleep(void* tag)
1479a747e4fSDavid du Colombier {
148*74f16c81SDavid du Colombier 	void *value;
1499a747e4fSDavid du Colombier 
1509a747e4fSDavid du Colombier 	for(;;){
151*74f16c81SDavid du Colombier 		value = rendezvous(tag, (void*)0x22a891b8);
152*74f16c81SDavid du Colombier 		if(value == (void*)0x7f7713f9)
1539a747e4fSDavid du Colombier 			break;
154*74f16c81SDavid du Colombier 		if(tag != (void*)~0)
1559a747e4fSDavid du Colombier 			panic("_rendsleep: rendezvous mismatch");
1569a747e4fSDavid du Colombier 	}
1579a747e4fSDavid du Colombier }
1589a747e4fSDavid du Colombier 
1599a747e4fSDavid du Colombier void
_rendwakeup(void * tag)160*74f16c81SDavid du Colombier _rendwakeup(void* tag)
1619a747e4fSDavid du Colombier {
162*74f16c81SDavid du Colombier 	void *value;
1639a747e4fSDavid du Colombier 
1649a747e4fSDavid du Colombier 	for(;;){
165*74f16c81SDavid du Colombier 		value = rendezvous(tag, (void*)0x7f7713f9);
166*74f16c81SDavid du Colombier 		if(value == (void*)0x22a891b8)
1679a747e4fSDavid du Colombier 			break;
168*74f16c81SDavid du Colombier 		if(tag != (void*)~0)
1699a747e4fSDavid du Colombier 			panic("_rendwakeup: rendezvous mismatch");
1709a747e4fSDavid du Colombier 	}
1719a747e4fSDavid du Colombier }
1729a747e4fSDavid du Colombier 
1739a747e4fSDavid du Colombier void
rendsleep(Rendez * r,int (* f)(void *),void * arg)1749a747e4fSDavid du Colombier rendsleep(Rendez *r, int (*f)(void*), void *arg)
1759a747e4fSDavid du Colombier {
1769a747e4fSDavid du Colombier 	lock(&up->rlock);
1779a747e4fSDavid du Colombier 	up->r = r;
1789a747e4fSDavid du Colombier 	unlock(&up->rlock);
1799a747e4fSDavid du Colombier 
1809a747e4fSDavid du Colombier 	lock(r);
1819a747e4fSDavid du Colombier 
1829a747e4fSDavid du Colombier 	/*
1839a747e4fSDavid du Colombier 	 * if condition happened, never mind
1849a747e4fSDavid du Colombier 	 */
1859a747e4fSDavid du Colombier 	if(up->intr || f(arg)){
1869a747e4fSDavid du Colombier 		unlock(r);
1879a747e4fSDavid du Colombier 		goto Done;
1889a747e4fSDavid du Colombier 	}
1899a747e4fSDavid du Colombier 
1909a747e4fSDavid du Colombier 	/*
1919a747e4fSDavid du Colombier 	 * now we are committed to
1929a747e4fSDavid du Colombier 	 * change state and call scheduler
1939a747e4fSDavid du Colombier 	 */
1949a747e4fSDavid du Colombier 	if(r->p)
1959a747e4fSDavid du Colombier 		panic("double sleep");
1969a747e4fSDavid du Colombier 	r->p = up;
1979a747e4fSDavid du Colombier 	unlock(r);
1989a747e4fSDavid du Colombier 
199*74f16c81SDavid du Colombier 	_rendsleep(r);
2009a747e4fSDavid du Colombier 
2019a747e4fSDavid du Colombier Done:
2029a747e4fSDavid du Colombier 	lock(&up->rlock);
2039a747e4fSDavid du Colombier 	up->r = 0;
2049a747e4fSDavid du Colombier 	if(up->intr){
2059a747e4fSDavid du Colombier 		up->intr = 0;
2069a747e4fSDavid du Colombier 		unlock(&up->rlock);
2079a747e4fSDavid du Colombier 		error(Eintr);
2089a747e4fSDavid du Colombier 	}
2099a747e4fSDavid du Colombier 	unlock(&up->rlock);
2109a747e4fSDavid du Colombier }
2119a747e4fSDavid du Colombier 
2129a747e4fSDavid du Colombier int
rendwakeup(Rendez * r)2139a747e4fSDavid du Colombier rendwakeup(Rendez *r)
2149a747e4fSDavid du Colombier {
2159a747e4fSDavid du Colombier 	Proc *p;
2169a747e4fSDavid du Colombier 	int rv;
2179a747e4fSDavid du Colombier 
2189a747e4fSDavid du Colombier 	lock(r);
2199a747e4fSDavid du Colombier 	p = r->p;
2209a747e4fSDavid du Colombier 	rv = 0;
2219a747e4fSDavid du Colombier 	if(p){
2229a747e4fSDavid du Colombier 		r->p = nil;
223*74f16c81SDavid du Colombier 		_rendwakeup(r);
2249a747e4fSDavid du Colombier 		rv = 1;
2259a747e4fSDavid du Colombier 	}
2269a747e4fSDavid du Colombier 	unlock(r);
2279a747e4fSDavid du Colombier 	return rv;
2289a747e4fSDavid du Colombier }
2299a747e4fSDavid du Colombier 
2309a747e4fSDavid du Colombier void
rendintr(void * v)2319a747e4fSDavid du Colombier rendintr(void *v)
2329a747e4fSDavid du Colombier {
2339a747e4fSDavid du Colombier 	Proc *p;
2349a747e4fSDavid du Colombier 
2359a747e4fSDavid du Colombier 	p = v;
2369a747e4fSDavid du Colombier 	lock(&p->rlock);
2379a747e4fSDavid du Colombier 	p->intr = 1;
2389a747e4fSDavid du Colombier 	if(p->r)
2399a747e4fSDavid du Colombier 		rendwakeup(p->r);
2409a747e4fSDavid du Colombier 	unlock(&p->rlock);
2419a747e4fSDavid du Colombier }
2429a747e4fSDavid du Colombier 
2439a747e4fSDavid du Colombier void
rendclearintr(void)2449a747e4fSDavid du Colombier rendclearintr(void)
2459a747e4fSDavid du Colombier {
2469a747e4fSDavid du Colombier 	lock(&up->rlock);
2479a747e4fSDavid du Colombier 	up->intr = 0;
2489a747e4fSDavid du Colombier 	unlock(&up->rlock);
2499a747e4fSDavid du Colombier }
2509a747e4fSDavid du Colombier 
251