## diffname gnot/sysproc.c 1990/03091 ## diff -e /dev/null /n/bootesdump/1990/03091/sys/src/9/68020/sysproc.c 0a #include "u.h" #include "lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "ureg.h" #include "errno.h" #include int shargs(char*, int, char**); long sysr1(ulong *arg) { print("[%d] r1 = %d\n", u->p->pid, arg[0]); return 0; } long sysfork(ulong *arg) { Proc *p; Seg *s; Page *np, *op; ulong usp, upa, pid; Chan *c; Orig *o; int n, on, i; int lastvar; /* used to compute stack address */ /* * Kernel stack */ p = newproc(); p->upage = newpage(1, 0, USERADDR|(p->pid&0xFFFF)); upa = p->upage->pa|KZERO; /* * Save time: only copy u-> data and useful stack */ memcpy((void*)upa, u, sizeof(User)); n = USERADDR+BY2PG - (ulong)&lastvar; n = (n+32) & ~(BY2WD-1); /* be safe & word align */ memcpy((void*)(upa+BY2PG-n), (void*)((u->p->upage->pa|KZERO)+BY2PG-n), n); ((User *)upa)->p = p; /* * User stack */ p->seg[SSEG] = u->p->seg[SSEG]; s = &p->seg[SSEG]; s->proc = p; on = (s->maxva-s->minva)>>PGSHIFT; usp = ((Ureg*)UREGADDR)->sp; if(usp >= USTKTOP) panic("fork bad usp %lux", usp); if(usp < u->p->seg[SSEG].minva) s->minva = u->p->seg[SSEG].minva; else s->minva = usp & ~(BY2PG-1); usp = s->minva & (BY2PG-1); /* just low bits */ s->maxva = USTKTOP; n = (s->maxva-s->minva)>>PGSHIFT; s->o = neworig(s->minva, n, OWRPERM, 0); lock(s->o); /* * Only part of last stack page */ for(i=0; ip->seg[SSEG].o->pte[i+(on-n)].page; if(op){ np = newpage(1, s->o, op->va); p->seg[SSEG].o->pte[i].page = np; if(i == 0){ /* only part of last stack page */ memset((void*)(np->pa|KZERO), 0, usp); memcpy((void*)((np->pa+usp)|KZERO), (void*)((op->pa+usp)|KZERO), BY2PG-usp); }else /* all of higher pages */ memcpy((void*)(np->pa|KZERO), (void*)(op->pa|KZERO), BY2PG); } } unlock(s->o); /* * Duplicate segments */ for(s=&u->p->seg[0], n=0; no == 0) continue; p->seg[n] = *s; p->seg[n].proc = p; o = s->o; lock(o); o->nproc++; if(s->mod) forkmod(s, &p->seg[n], p); unlock(o); } /* * Refs */ incref(u->dot); for(n=0; n<=u->maxfd; n++) if(c = u->fd[n]) /* assign = */ incref(c); /* * Committed. Link into hierarchy */ lock(&p->kidlock); lock(&u->p->kidlock); if(u->p->kid == 0){ p->sib = p; u->p->kid = p; }else{ p->sib = u->p->kid->sib; u->p->kid->sib = p; } unlock(&u->p->kidlock); unlock(&p->kidlock); /* * Sched */ if(setlabel(&p->sched)){ u->p = p; p->state = Running; p->mach = m; m->proc = p; spllo(); return 0; } p->pop = u->p; p->parent = u->p; p->parentpid = u->p->pid; p->pgrp = u->p->pgrp; incref(p->pgrp); u->p->nchild++; pid = p->pid; memset(p->time, 0, sizeof(p->time)); p->time[TReal] = MACHP(0)->ticks; memcpy(p->text, u->p->text, NAMELEN); ready(p); flushmmu(); return pid; } long sysexec(ulong *arg) { Proc *p; Seg *s; ulong l, t, d, b, v; int i; Chan *tc; Orig *o; char **argv, **argp; char *a, *charp, *file; char *progarg[sizeof(Exec)/2+1], elem[NAMELEN]; ulong ssize, spage, nargs, nbytes, n; ulong *sp; int indir; Exec exec; char line[sizeof(Exec)]; p = u->p; validaddr(arg[0], 1, 0); file = (char*)arg[0]; indir = 0; Header: tc = namec(file, Aopen, OEXEC, 0); if(waserror()){ close(tc); nexterror(); } if(!indir) strcpy(elem, u->elem); n = (*devtab[tc->type].read)(tc, &exec, sizeof(Exec)); if(n < 2) Err: error(0, Ebadexec); if(n==sizeof(Exec) && exec.magic==A_MAGIC){ if((exec.text&KZERO) || (ulong)exec.entry < UTZERO+sizeof(Exec) || (ulong)exec.entry >= UTZERO+sizeof(Exec)+exec.text) goto Err; goto Binary; } /* * Process #! /bin/sh args ... */ memcpy(line, &exec, sizeof(Exec)); if(indir || line[0]!='#' || line[1]!='!') goto Err; n = shargs(line, n, progarg); if(n == 0) goto Err; indir = 1; /* * First arg becomes complete file name */ progarg[n++] = file; progarg[n] = 0; validaddr(arg[1], BY2WD, 1); arg[1] += BY2WD; file = progarg[0]; progarg[0] = elem; close(tc); poperror(); goto Header; Binary: t = (UTZERO+sizeof(Exec)+exec.text+(BY2PG-1)) & ~(BY2PG-1); /* * Last partial page of data goes into BSS. */ d = (t + exec.data) & ~(BY2PG-1); b = (t + exec.data + exec.bss + (BY2PG-1)) & ~(BY2PG-1); if((t|d|b) & KZERO) error(0, Ebadexec); /* * Args: pass 1: count */ nbytes = 0; nargs = 0; if(indir){ argp = progarg; while(*argp){ a = *argp++; nbytes += strlen(a) + 1; nargs++; } } evenaddr(arg[1]); argp = (char**)arg[1]; validaddr((ulong)argp, BY2WD, 0); while(*argp){ a = *argp++; if(((ulong)argp&(BY2PG-1)) < BY2WD) validaddr((ulong)argp, BY2WD, 0); validaddr((ulong)a, 1, 0); nbytes += (vmemchr(a, 0, 0xFFFFFFFF) - a) + 1; nargs++; } ssize = BY2WD*(nargs+1) + ((nbytes+(BY2WD-1)) & ~(BY2WD-1)); spage = (ssize+(BY2PG-1)) >> PGSHIFT; /* * Build the stack segment, putting it in kernel virtual for the moment */ s = &p->seg[ESEG]; s->proc = p; s->o = neworig(TSTKTOP-(spage<minva = s->o->va; s->maxva = TSTKTOP; /* * Args: pass 2: assemble; the pages will be faulted in */ argv = (char**)(TSTKTOP - ssize); charp = (char*)(TSTKTOP - nbytes); if(indir) argp = progarg; else argp = (char**)arg[1]; for(i=0; itext, elem, NAMELEN); /* * Committed. Free old memory */ freesegs(ESEG); /* * Text. Shared. */ s = &p->seg[TSEG]; s->proc = p; o = lookorig(UTZERO, (t-UTZERO)>>PGSHIFT, OCACHED, tc); if(o == 0){ o = neworig(UTZERO, (t-UTZERO)>>PGSHIFT, OCACHED, tc); o->minca = 0; o->maxca = sizeof(Exec)+exec.text; } s->o = o; s->minva = UTZERO; s->maxva = t; s->mod = 0; /* * Data. Shared. */ s = &p->seg[DSEG]; s->proc = p; o = lookorig(t, (d-t)>>PGSHIFT, OWRPERM|OPURE|OCACHED, tc); if(o == 0){ o = neworig(t, (d-t)>>PGSHIFT, OWRPERM|OPURE|OCACHED, tc); o->minca = p->seg[TSEG].o->maxca; o->maxca = o->minca + (exec.data & ~(BY2PG-1)); } s->o = o; s->minva = t; s->maxva = d; s->mod = 0; /* * BSS. Created afresh, starting with last page of data. * BUG: should pick up the last page of data, which should be cached in the * data segment. */ s = &p->seg[BSEG]; s->proc = p; o = neworig(d, (b-d)>>PGSHIFT, OWRPERM, tc); o->minca = p->seg[DSEG].o->maxca; o->maxca = o->minca + (exec.data & (BY2PG-1)); s->o = o; s->minva = d; s->maxva = b; s->mod = 0; close(tc); /* * Move the stack */ s = &p->seg[SSEG]; *s = p->seg[ESEG]; p->seg[ESEG].o = 0; o = s->o; o->va += (USTKTOP-TSTKTOP); s->minva = o->va; s->maxva = USTKTOP; lock(o); for(i=0; inpte; i++) o->pte[i].page->va += (USTKTOP-TSTKTOP); unlock(o); flushmmu(); ((Ureg*)UREGADDR)->pc = exec.entry - 4; sp = (ulong*)(USTKTOP - ssize); *--sp = nargs; ((Ureg*)UREGADDR)->sp = (ulong)sp; lock(&p->debug); u->nnote = 0; u->notify = 0; u->notified = 0; unlock(&p->debug); return 0; } int shargs(char *s, int n, char **ap) { int i; s += 2, n -= 2; /* skip #! */ for(i=0; s[i]!='\n'; i++) if(i == n-1) return 0; s[i] = 0; *ap = 0; i = 0; for(;;){ while(*s==' ' || *s=='\t') s++; if(*s == 0) break; i++; *ap++ = s; *ap = 0; while(*s && *s!=' ' && *s!='\t') s++; if(*s == 0) break; else *s++ = 0; } return i; } int return0(void *a) { return 0; } long syssleep(ulong *arg) { int ms; tsleep(&u->p->sleep, return0, 0, arg[0]); return 0; } long sysexits(ulong *arg) { char *status; status = (char*)arg[0]; if(status){ if(waserror()) status = "invalid exit string"; else{ validaddr((ulong)status, 1, 0); vmemchr(status, 0, ERRLEN); } } pexit(status, 1); } long syswait(ulong *arg) { if(arg[0]){ validaddr(arg[0], sizeof(Waitmsg), 1); evenaddr(arg[0]); } return pwait((Waitmsg*)arg[0]); } long syslasterr(ulong *arg) { Error *e; validaddr(arg[0], sizeof u->error, 1); evenaddr(arg[0]); e = (Error *)arg[0]; memcpy(e, &u->error, sizeof u->error); memset(&u->error, 0, sizeof u->error); e->type = devchar[e->type]; return 0; } long syserrstr(ulong *arg) { Error *e, err; char buf[ERRLEN]; validaddr(arg[1], ERRLEN, 1); e = &err; if(arg[0]){ validaddr(arg[0], sizeof u->error, 0); memcpy(e, (Error*)arg[0], sizeof(Error)); e->type = devno(e->type, 1); if(e->type == -1){ e->type = 0; e->code = Egreg+1; /* -> "no such error" */ } }else{ memcpy(e, &u->error, sizeof(Error)); memset(&u->error, 0, sizeof(Error)); } (*devtab[e->type].errstr)(e, buf); memcpy((char*)arg[1], buf, sizeof buf); return 0; } long sysforkpgrp(ulong *arg) { Pgrp *pg; pg = newpgrp(); if(waserror()){ closepgrp(pg); nexterror(); } if(arg[0] == 0) pgrpcpy(pg, u->p->pgrp); closepgrp(u->p->pgrp); u->p->pgrp = pg; return pg->pgrpid; } long sysnotify(ulong *arg) { validaddr(arg[0], sizeof(ulong), 0); u->notify = (int(*)(void*, char*))(arg[0]); return 0; } long sysnoted(ulong *arg) { if(u->notified == 0) error(0, Egreg); return 0; } /* * Temporary; should be replaced by a generalized segment control operator */ long sysbrk_(ulong *arg) { if(segaddr(&u->p->seg[BSEG], u->p->seg[BSEG].minva, arg[0]) == 0) error(0, Esegaddr); return 0; } . ## diffname gnot/sysproc.c 1990/0312 ## diff -e /n/bootesdump/1990/03091/sys/src/9/68020/sysproc.c /n/bootesdump/1990/0312/sys/src/9/68020/sysproc.c 353c ((Ureg*)UREGADDR)->usp = (ulong)sp; . 350c ((Ureg*)UREGADDR)->pc = exec.entry; . 191a print("do #! magic=%lux size=%d\n", exec.magic, n); . 185a } . 184c || (ulong)exec.entry >= UTZERO+sizeof(Exec)+exec.text){ print("bad header sizes\n"); . 180a } . 178c if(n < 2){ print("short read\n"); . 176a print("offset %lux\n", tc->offset); . 54c usp = ((Ureg*)UREGADDR)->usp; . ## diffname gnot/sysproc.c 1990/0315 ## diff -e /n/bootesdump/1990/0312/sys/src/9/68020/sysproc.c /n/bootesdump/1990/0315/sys/src/9/68020/sysproc.c 177d ## diffname gnot/sysproc.c 1990/0317 ## diff -e /n/bootesdump/1990/0315/sys/src/9/68020/sysproc.c /n/bootesdump/1990/0317/sys/src/9/68020/sysproc.c 196d ## diffname gnot/sysproc.c 1990/0504 ## diff -e /n/bootesdump/1990/0317/sys/src/9/68020/sysproc.c /n/bootesdump/1990/0504/sys/src/9/68020/sysproc.c 189d 186,187c || (ulong)exec.entry >= UTZERO+sizeof(Exec)+exec.text) . 182d 178,179c if(n < 2) . ## diffname gnot/sysproc.c 1990/06021 ## diff -e /n/bootesdump/1990/0504/sys/src/9/68020/sysproc.c /n/bootesdump/1990/06021/sys/src/9/68020/sysproc.c 79c memcpy((void*)k->va, (void*)op->va, BY2PG); kunmap(k); . 75,77c memset((void*)k->va, 0, usp); memcpy((void*)(k->va+usp), (void*)(op->va+usp), BY2PG-usp); . 72a k = kmap(np); . 45a kunmap(k); . 44c memcpy((void*)(upa+BY2PG-n), (void*)(USERADDR+BY2PG-n), n); . 37c k = kmap(p->upage); upa = k->va; . 28a KMap *k; . ## diffname gnot/sysproc.c 1990/0614 ## diff -e /n/bootesdump/1990/06021/sys/src/9/68020/sysproc.c /n/bootesdump/1990/0614/sys/src/9/68020/sysproc.c 84c memcpy((void*)VA(k), (void*)op->va, BY2PG); . 80,81c memset((void*)VA(k), 0, usp); memcpy((void*)(VA(k)+usp), . 39c upa = VA(k); . ## diffname gnot/sysproc.c 1990/0619 ## diff -e /n/bootesdump/1990/0614/sys/src/9/68020/sysproc.c /n/bootesdump/1990/0619/sys/src/9/68020/sysproc.c 407,408d ## diffname gnot/sysproc.c 1990/08141 ## diff -e /n/bootesdump/1990/0619/sys/src/9/68020/sysproc.c /n/bootesdump/1990/08141/sys/src/9/68020/sysproc.c 289a /* * Close on exec */ for(i=0; i<=u->maxfd; i++) if((c=u->fd[i]) && c->flag&CCEXEC){ close(c); fdclose(i); } . 160c Chan *tc, *c; . ## diffname gnot/sysproc.c 1990/08163 ## diff -e /n/bootesdump/1990/08141/sys/src/9/68020/sysproc.c /n/bootesdump/1990/08163/sys/src/9/68020/sysproc.c 372a splhi(); m->fpstate = FPinit; p->fpstate = FPinit; fprestore((FPsave*)&fpnull); spllo(); . 163a long fpnull = 0; . ## diffname gnot/sysproc.c 1990/0918 ## diff -e /n/bootesdump/1990/08163/sys/src/9/68020/sysproc.c /n/bootesdump/1990/0918/sys/src/9/68020/sysproc.c 533a Return: u->p->bssend = addr; . 531a ulong addr; Seg *s; addr = arg[0]; if(addr < u->p->bssend) error(0, Esegaddr); if(addr <= ((u->p->bssend+(BY2PG-1))&~(BY2PG-1))) /* still in DSEG */ goto Return; . 349a p->bssend = bssend; . 340,342c o = neworig(d, (b-d)>>PGSHIFT, OWRPERM, 0); o->minca = 0; o->maxca = 0; . 334,336c * BSS. Created afresh. . 326c o->maxca = o->minca + exec.data; . 221,225c d = (t + exec.data + (BY2PG-1)) & ~(BY2PG-1); bssend = t + exec.data + exec.bss; b = (bssend + (BY2PG-1)) & ~(BY2PG-1); . 166c ulong ssize, spage, nargs, nbytes, n, bssend; . ## diffname gnot/sysproc.c 1990/0921 ## diff -e /n/bootesdump/1990/0918/sys/src/9/68020/sysproc.c /n/bootesdump/1990/0921/sys/src/9/68020/sysproc.c 363a clearmmucache(); . 43a clearmmucache(); . ## diffname gnot/sysproc.c 1990/0928 ## diff -e /n/bootesdump/1990/0921/sys/src/9/68020/sysproc.c /n/bootesdump/1990/0928/sys/src/9/68020/sysproc.c 365d 44d ## diffname gnot/sysproc.c 1990/1004 ## diff -e /n/bootesdump/1990/0928/sys/src/9/68020/sysproc.c /n/bootesdump/1990/1004/sys/src/9/68020/sysproc.c 363a clearmmucache(); . 149a clearmmucache(); . 131,135c clearmmucache(); restore(); . 43a clearmmucache(); . ## diffname gnot/sysproc.c 1990/1009 ## diff -e /n/bootesdump/1990/1004/sys/src/9/68020/sysproc.c /n/bootesdump/1990/1009/sys/src/9/68020/sysproc.c 502a else memcpy(pg->user, u->p->pgrp->user, NAMELEN); . ## diffname gnot/sysproc.c 1990/1115 ## diff -e /n/bootesdump/1990/1009/sys/src/9/68020/sysproc.c /n/bootesdump/1990/1115/sys/src/9/68020/sysproc.c 541a } . 540c if(segaddr(&u->p->seg[BSEG], u->p->seg[BSEG].minva, arg[0]) == 0){ pprint("bad segaddr in brk\n"); pexit("Suicide", 0); . 537a } . 536c if(addr < u->p->bssend){ pprint("addr below bss\n"); pexit("Suicide", 0); . ## diffname gnot/sysproc.c 1990/11211 ## diff -e /n/bootesdump/1990/1115/sys/src/9/68020/sysproc.c /n/bootesdump/1990/11211/sys/src/9/68020/sysproc.c 546c error(Esegaddr); . 539c error(Esegaddr); . 522c error(Egreg); . 472,487c validaddr(arg[0], ERRLEN, 1); memcpy((char*)arg[0], u->error, ERRLEN); . 469d 455,463c pprint("deprecated system call"); pexit("Suicide", 0); . 453c sysdeath(ulong *arg) . 224c error(Ebadexec); . 186c error(Ebadexec); . ## diffname gnot/sysproc.c 1990/1124 ## diff -e /n/bootesdump/1990/11211/sys/src/9/68020/sysproc.c /n/bootesdump/1990/1124/sys/src/9/68020/sysproc.c 136d 115,128d ## diffname gnot/sysproc.c 1990/1211 # deleted ## diff -e /n/bootesdump/1990/1124/sys/src/9/68020/sysproc.c /n/bootesdump/1990/1211/sys/src/9/68020/sysproc.c 1,514d