summaryrefslogtreecommitdiff
path: root/sys/src/cmd/vnc/compat.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/vnc/compat.c
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/vnc/compat.c')
-rwxr-xr-xsys/src/cmd/vnc/compat.c250
1 files changed, 250 insertions, 0 deletions
diff --git a/sys/src/cmd/vnc/compat.c b/sys/src/cmd/vnc/compat.c
new file mode 100755
index 000000000..2b408a546
--- /dev/null
+++ b/sys/src/cmd/vnc/compat.c
@@ -0,0 +1,250 @@
+#include <u.h>
+#include <libc.h>
+#include "compat.h"
+#include "error.h"
+
+#include "errstr.h"
+
+ulong kerndate;
+Proc **privup;
+char *eve;
+extern void *mainmem;
+
+void
+_assert(char *fmt)
+{
+ panic("assert failed: %s", fmt);
+}
+
+int
+errdepth(int ed)
+{
+ if(ed >= 0 && up->nerrlab != ed)
+ panic("unbalanced error depth: expected %d got %d\n", ed, up->nerrlab);
+ return up->nerrlab;
+}
+
+void
+newup(char *name)
+{
+ up = smalloc(sizeof(Proc));
+ up->user = eve;
+ strncpy(up->name, name, KNAMELEN-1);
+ up->name[KNAMELEN-1] = '\0';
+}
+
+void
+kproc(char *name, void (*f)(void *), void *a)
+{
+ int pid;
+
+ pid = rfork(RFPROC|RFMEM|RFNOWAIT);
+ switch(pid){
+ case -1:
+ panic("can't make new thread: %r");
+ case 0:
+ break;
+ default:
+ return;
+ }
+
+ newup(name);
+ if(!waserror())
+ (*f)(a);
+ _exits(nil);
+}
+
+void
+kexit(void)
+{
+ _exits(nil);
+}
+
+void
+initcompat(void)
+{
+ rfork(RFREND);
+ privup = privalloc();
+ kerndate = seconds();
+ eve = getuser();
+ newup("main");
+}
+
+int
+openmode(ulong o)
+{
+ o &= ~(OTRUNC|OCEXEC|ORCLOSE);
+ if(o > OEXEC)
+ error(Ebadarg);
+ if(o == OEXEC)
+ return OREAD;
+ return o;
+}
+
+void
+panic(char *fmt, ...)
+{
+ char buf[512];
+ char buf2[512];
+ va_list va;
+
+ va_start(va, fmt);
+ vseprint(buf, buf+sizeof(buf), fmt, va);
+ va_end(va);
+ sprint(buf2, "panic: %s\n", buf);
+ write(2, buf2, strlen(buf2));
+
+ exits("error");
+}
+
+void*
+smalloc(ulong n)
+{
+ void *p;
+
+ p = mallocz(n, 1);
+ if(p == nil)
+ panic("out of memory");
+ setmalloctag(p, getcallerpc(&n));
+ return p;
+}
+
+long
+seconds(void)
+{
+ return time(nil);
+}
+
+void
+error(char *err)
+{
+ strncpy(up->error, err, ERRMAX);
+ nexterror();
+}
+
+void
+nexterror(void)
+{
+ longjmp(up->errlab[--up->nerrlab], 1);
+}
+
+int
+readstr(ulong off, char *buf, ulong n, char *str)
+{
+ int size;
+
+ size = strlen(str);
+ if(off >= size)
+ return 0;
+ if(off+n > size)
+ n = size-off;
+ memmove(buf, str+off, n);
+ return n;
+}
+
+void
+_rendsleep(void* tag)
+{
+ void *value;
+
+ for(;;){
+ value = rendezvous(tag, (void*)0x22a891b8);
+ if(value == (void*)0x7f7713f9)
+ break;
+ if(tag != (void*)~0)
+ panic("_rendsleep: rendezvous mismatch");
+ }
+}
+
+void
+_rendwakeup(void* tag)
+{
+ void *value;
+
+ for(;;){
+ value = rendezvous(tag, (void*)0x7f7713f9);
+ if(value == (void*)0x22a891b8)
+ break;
+ if(tag != (void*)~0)
+ panic("_rendwakeup: rendezvous mismatch");
+ }
+}
+
+void
+rendsleep(Rendez *r, int (*f)(void*), void *arg)
+{
+ lock(&up->rlock);
+ up->r = r;
+ unlock(&up->rlock);
+
+ lock(r);
+
+ /*
+ * if condition happened, never mind
+ */
+ if(up->intr || f(arg)){
+ unlock(r);
+ goto Done;
+ }
+
+ /*
+ * now we are committed to
+ * change state and call scheduler
+ */
+ if(r->p)
+ panic("double sleep");
+ r->p = up;
+ unlock(r);
+
+ _rendsleep(r);
+
+Done:
+ lock(&up->rlock);
+ up->r = 0;
+ if(up->intr){
+ up->intr = 0;
+ unlock(&up->rlock);
+ error(Eintr);
+ }
+ unlock(&up->rlock);
+}
+
+int
+rendwakeup(Rendez *r)
+{
+ Proc *p;
+ int rv;
+
+ lock(r);
+ p = r->p;
+ rv = 0;
+ if(p){
+ r->p = nil;
+ _rendwakeup(r);
+ rv = 1;
+ }
+ unlock(r);
+ return rv;
+}
+
+void
+rendintr(void *v)
+{
+ Proc *p;
+
+ p = v;
+ lock(&p->rlock);
+ p->intr = 1;
+ if(p->r)
+ rendwakeup(p->r);
+ unlock(&p->rlock);
+}
+
+void
+rendclearintr(void)
+{
+ lock(&up->rlock);
+ up->intr = 0;
+ unlock(&up->rlock);
+}
+