## 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 <a.out.h>
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; i<n; i++){
op = u->p->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; n<NSEG; n++, s++){
if(n == SSEG) /* already done */
continue;
if(s->o == 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<<PGSHIFT), spage, OWRPERM, 0);
s->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; i<nargs; i++){
if(indir && *argp==0){
indir = 0;
argp = (char**)arg[1];
}
*argv++ = charp + (USTKTOP-TSTKTOP);
n = strlen(*argp) + 1;
memcpy(charp, *argp++, n);
charp += n;
}
memcpy(p->text, 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; i<o->npte; 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
|