#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 voidLines 1–500 of 711. Load more
#include <u.h> #include <libc.h> #include <thread.h> #include "dat.h" #include "fns.h" #include </sys/src/libc/9syscall/sys.h> static u32int arg(int n) { /* no locking necessary, since we're on the stack */ return *(u32int*) vaddrnol(P->R[13] + 4 + 4 * n, 4); } static u64int argv(int n) { return arg(n) | ((u64int)arg(n+1) << 32); } static void sysopen(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 void syscreate(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 void sysclose(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 void syspread(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 void syspwrite(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 void sysseek(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 void sysfd2path(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 void sysstat(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 void sysfstat(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 void syswstat(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 void sysfwstat(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 void sysexits(void) { if(arg(0) == 0) exits(nil); else exits(vaddrnol(arg(0), 0)); } static void sysbrk(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 void syserrstr(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 void syschdir(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 void sysnotify(void) { u32int handler; handler = arg(0); if(systrace) fprint(2, "notify(%#ux)\n", handler); P->notehandler = handler; P->R[0] = 0; } static void sysnoted(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 void sysrfork(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 void sysexec(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 void sysawait(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 void syspipe(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 void sysdup(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 void syssleep(void) { u32int n; n = arg(0); if(systrace) fprint(2, "sleep(%d)\n", n); P->R[0] = noteerr(sleep(n), 0); } static void