13e12c5d1SDavid du Colombier #include "u.h" 23e12c5d1SDavid du Colombier #include "../port/lib.h" 33e12c5d1SDavid du Colombier #include "mem.h" 43e12c5d1SDavid du Colombier #include "dat.h" 53e12c5d1SDavid du Colombier #include "fns.h" 63e12c5d1SDavid du Colombier #include "../port/error.h" 73e12c5d1SDavid du Colombier 83e12c5d1SDavid du Colombier #include <a.out.h> 93e12c5d1SDavid du Colombier 103e12c5d1SDavid du Colombier int shargs(char*, int, char**); 113e12c5d1SDavid du Colombier 129a747e4fSDavid du Colombier Ref sysr1ref; 139a747e4fSDavid du Colombier 143e12c5d1SDavid du Colombier long 153e12c5d1SDavid du Colombier sysr1(ulong *arg) 163e12c5d1SDavid du Colombier { 179a747e4fSDavid du Colombier long a; 189a747e4fSDavid du Colombier 199a747e4fSDavid du Colombier a = *arg; 209a747e4fSDavid du Colombier if(a > 0) 219a747e4fSDavid du Colombier return incref(&sysr1ref); 229a747e4fSDavid du Colombier if(a < 0) 239a747e4fSDavid du Colombier return decref(&sysr1ref); 249a747e4fSDavid du Colombier return sysr1ref.ref; 259a747e4fSDavid du Colombier 269a747e4fSDavid du Colombier /* 279a747e4fSDavid du Colombier extern int chandebug; 289a747e4fSDavid du Colombier extern void dumpmount(void); 299a747e4fSDavid du Colombier 307dd7cddfSDavid du Colombier print("[%s %s %lud] r1 = %lud\n", up->user, up->text, up->pid, arg[0]); 319a747e4fSDavid du Colombier chandebug=!chandebug; 329a747e4fSDavid du Colombier if(chandebug) 339a747e4fSDavid du Colombier dumpmount(); 349a747e4fSDavid du Colombier 353e12c5d1SDavid du Colombier return 0; 369a747e4fSDavid du Colombier */ 373e12c5d1SDavid du Colombier } 383e12c5d1SDavid du Colombier 393e12c5d1SDavid du Colombier long 403e12c5d1SDavid du Colombier sysrfork(ulong *arg) 413e12c5d1SDavid du Colombier { 427dd7cddfSDavid du Colombier Proc *p; 433e12c5d1SDavid du Colombier int n, i; 447dd7cddfSDavid du Colombier Fgrp *ofg; 457dd7cddfSDavid du Colombier Pgrp *opg; 467dd7cddfSDavid du Colombier Rgrp *org; 477dd7cddfSDavid du Colombier Egrp *oeg; 487dd7cddfSDavid du Colombier ulong pid, flag; 497dd7cddfSDavid du Colombier Mach *wm; 503e12c5d1SDavid du Colombier 513e12c5d1SDavid du Colombier flag = arg[0]; 523e12c5d1SDavid du Colombier /* Check flags before we commit */ 533e12c5d1SDavid du Colombier if((flag & (RFFDG|RFCFDG)) == (RFFDG|RFCFDG)) 543e12c5d1SDavid du Colombier error(Ebadarg); 553e12c5d1SDavid du Colombier if((flag & (RFNAMEG|RFCNAMEG)) == (RFNAMEG|RFCNAMEG)) 563e12c5d1SDavid du Colombier error(Ebadarg); 573e12c5d1SDavid du Colombier if((flag & (RFENVG|RFCENVG)) == (RFENVG|RFCENVG)) 583e12c5d1SDavid du Colombier error(Ebadarg); 593e12c5d1SDavid du Colombier 607dd7cddfSDavid du Colombier if((flag&RFPROC) == 0) { 617dd7cddfSDavid du Colombier if(flag & (RFMEM|RFNOWAIT)) 627dd7cddfSDavid du Colombier error(Ebadarg); 637dd7cddfSDavid du Colombier if(flag & (RFFDG|RFCFDG)) { 647dd7cddfSDavid du Colombier ofg = up->fgrp; 657dd7cddfSDavid du Colombier if(flag & RFFDG) 667dd7cddfSDavid du Colombier up->fgrp = dupfgrp(ofg); 677dd7cddfSDavid du Colombier else 687dd7cddfSDavid du Colombier up->fgrp = dupfgrp(nil); 697dd7cddfSDavid du Colombier closefgrp(ofg); 707dd7cddfSDavid du Colombier } 717dd7cddfSDavid du Colombier if(flag & (RFNAMEG|RFCNAMEG)) { 727dd7cddfSDavid du Colombier opg = up->pgrp; 737dd7cddfSDavid du Colombier up->pgrp = newpgrp(); 747dd7cddfSDavid du Colombier if(flag & RFNAMEG) 757dd7cddfSDavid du Colombier pgrpcpy(up->pgrp, opg); 767dd7cddfSDavid du Colombier /* inherit noattach */ 777dd7cddfSDavid du Colombier up->pgrp->noattach = opg->noattach; 787dd7cddfSDavid du Colombier closepgrp(opg); 797dd7cddfSDavid du Colombier } 807dd7cddfSDavid du Colombier if(flag & RFNOMNT) 817dd7cddfSDavid du Colombier up->pgrp->noattach = 1; 827dd7cddfSDavid du Colombier if(flag & RFREND) { 837dd7cddfSDavid du Colombier org = up->rgrp; 847dd7cddfSDavid du Colombier up->rgrp = newrgrp(); 857dd7cddfSDavid du Colombier closergrp(org); 867dd7cddfSDavid du Colombier } 877dd7cddfSDavid du Colombier if(flag & (RFENVG|RFCENVG)) { 887dd7cddfSDavid du Colombier oeg = up->egrp; 897dd7cddfSDavid du Colombier up->egrp = smalloc(sizeof(Egrp)); 907dd7cddfSDavid du Colombier up->egrp->ref = 1; 917dd7cddfSDavid du Colombier if(flag & RFENVG) 927dd7cddfSDavid du Colombier envcpy(up->egrp, oeg); 937dd7cddfSDavid du Colombier closeegrp(oeg); 947dd7cddfSDavid du Colombier } 957dd7cddfSDavid du Colombier if(flag & RFNOTEG) 967dd7cddfSDavid du Colombier up->noteid = incref(¬eidalloc); 977dd7cddfSDavid du Colombier return 0; 987dd7cddfSDavid du Colombier } 997dd7cddfSDavid du Colombier 1003e12c5d1SDavid du Colombier p = newproc(); 1013e12c5d1SDavid du Colombier 1027dd7cddfSDavid du Colombier p->fpsave = up->fpsave; 1037dd7cddfSDavid du Colombier p->scallnr = up->scallnr; 1047dd7cddfSDavid du Colombier p->s = up->s; 1057dd7cddfSDavid du Colombier p->nerrlab = 0; 1067dd7cddfSDavid du Colombier p->slash = up->slash; 1077dd7cddfSDavid du Colombier p->dot = up->dot; 1087dd7cddfSDavid du Colombier incref(p->dot); 1093e12c5d1SDavid du Colombier 1107dd7cddfSDavid du Colombier memmove(p->note, up->note, sizeof(p->note)); 1119a747e4fSDavid du Colombier p->privatemem = up->privatemem; 112b7b24591SDavid du Colombier p->noswap = up->noswap; 1137dd7cddfSDavid du Colombier p->nnote = up->nnote; 1147dd7cddfSDavid du Colombier p->notified = 0; 1157dd7cddfSDavid du Colombier p->lastnote = up->lastnote; 1167dd7cddfSDavid du Colombier p->notify = up->notify; 1177dd7cddfSDavid du Colombier p->ureg = up->ureg; 1187dd7cddfSDavid du Colombier p->dbgreg = 0; 1193e12c5d1SDavid du Colombier 1203e12c5d1SDavid du Colombier /* Make a new set of memory segments */ 1213e12c5d1SDavid du Colombier n = flag & RFMEM; 1227dd7cddfSDavid du Colombier qlock(&p->seglock); 1237dd7cddfSDavid du Colombier if(waserror()){ 1247dd7cddfSDavid du Colombier qunlock(&p->seglock); 1257dd7cddfSDavid du Colombier nexterror(); 1267dd7cddfSDavid du Colombier } 1273e12c5d1SDavid du Colombier for(i = 0; i < NSEG; i++) 1287dd7cddfSDavid du Colombier if(up->seg[i]) 1297dd7cddfSDavid du Colombier p->seg[i] = dupseg(up->seg, i, n); 1307dd7cddfSDavid du Colombier qunlock(&p->seglock); 1317dd7cddfSDavid du Colombier poperror(); 1323e12c5d1SDavid du Colombier 1333e12c5d1SDavid du Colombier /* File descriptors */ 1343e12c5d1SDavid du Colombier if(flag & (RFFDG|RFCFDG)) { 1353e12c5d1SDavid du Colombier if(flag & RFFDG) 1367dd7cddfSDavid du Colombier p->fgrp = dupfgrp(up->fgrp); 1377dd7cddfSDavid du Colombier else 1387dd7cddfSDavid du Colombier p->fgrp = dupfgrp(nil); 1393e12c5d1SDavid du Colombier } 1403e12c5d1SDavid du Colombier else { 1417dd7cddfSDavid du Colombier p->fgrp = up->fgrp; 1423e12c5d1SDavid du Colombier incref(p->fgrp); 1433e12c5d1SDavid du Colombier } 1443e12c5d1SDavid du Colombier 1453e12c5d1SDavid du Colombier /* Process groups */ 1463e12c5d1SDavid du Colombier if(flag & (RFNAMEG|RFCNAMEG)) { 1473e12c5d1SDavid du Colombier p->pgrp = newpgrp(); 148bd389b36SDavid du Colombier if(flag & RFNAMEG) 1497dd7cddfSDavid du Colombier pgrpcpy(p->pgrp, up->pgrp); 1507dd7cddfSDavid du Colombier /* inherit noattach */ 1517dd7cddfSDavid du Colombier p->pgrp->noattach = up->pgrp->noattach; 1523e12c5d1SDavid du Colombier } 1533e12c5d1SDavid du Colombier else { 1547dd7cddfSDavid du Colombier p->pgrp = up->pgrp; 1553e12c5d1SDavid du Colombier incref(p->pgrp); 1563e12c5d1SDavid du Colombier } 1577dd7cddfSDavid du Colombier if(flag & RFNOMNT) 1587dd7cddfSDavid du Colombier up->pgrp->noattach = 1; 1597dd7cddfSDavid du Colombier 1607dd7cddfSDavid du Colombier if(flag & RFREND) 1617dd7cddfSDavid du Colombier p->rgrp = newrgrp(); 1627dd7cddfSDavid du Colombier else { 1637dd7cddfSDavid du Colombier incref(up->rgrp); 1647dd7cddfSDavid du Colombier p->rgrp = up->rgrp; 1657dd7cddfSDavid du Colombier } 1663e12c5d1SDavid du Colombier 1673e12c5d1SDavid du Colombier /* Environment group */ 1683e12c5d1SDavid du Colombier if(flag & (RFENVG|RFCENVG)) { 1693e12c5d1SDavid du Colombier p->egrp = smalloc(sizeof(Egrp)); 1703e12c5d1SDavid du Colombier p->egrp->ref = 1; 1713e12c5d1SDavid du Colombier if(flag & RFENVG) 1727dd7cddfSDavid du Colombier envcpy(p->egrp, up->egrp); 1733e12c5d1SDavid du Colombier } 1743e12c5d1SDavid du Colombier else { 1757dd7cddfSDavid du Colombier p->egrp = up->egrp; 1763e12c5d1SDavid du Colombier incref(p->egrp); 1773e12c5d1SDavid du Colombier } 1787dd7cddfSDavid du Colombier p->hang = up->hang; 1797dd7cddfSDavid du Colombier p->procmode = up->procmode; 1803e12c5d1SDavid du Colombier 1817dd7cddfSDavid du Colombier /* Craft a return frame which will cause the child to pop out of 1827dd7cddfSDavid du Colombier * the scheduler in user mode with the return register zero 1833e12c5d1SDavid du Colombier */ 1847dd7cddfSDavid du Colombier forkchild(p, up->dbgreg); 1853e12c5d1SDavid du Colombier 1867dd7cddfSDavid du Colombier p->parent = up; 1877dd7cddfSDavid du Colombier p->parentpid = up->pid; 1883e12c5d1SDavid du Colombier if(flag&RFNOWAIT) 1899a747e4fSDavid du Colombier p->parentpid = 0; 1903e12c5d1SDavid du Colombier else { 1917dd7cddfSDavid du Colombier lock(&up->exl); 1927dd7cddfSDavid du Colombier up->nchild++; 1937dd7cddfSDavid du Colombier unlock(&up->exl); 1943e12c5d1SDavid du Colombier } 1953e12c5d1SDavid du Colombier if((flag&RFNOTEG) == 0) 1967dd7cddfSDavid du Colombier p->noteid = up->noteid; 1973e12c5d1SDavid du Colombier 1987dd7cddfSDavid du Colombier p->fpstate = up->fpstate; 1993e12c5d1SDavid du Colombier pid = p->pid; 2003e12c5d1SDavid du Colombier memset(p->time, 0, sizeof(p->time)); 2013e12c5d1SDavid du Colombier p->time[TReal] = MACHP(0)->ticks; 2029a747e4fSDavid du Colombier 2039a747e4fSDavid du Colombier kstrdup(&p->text, up->text); 2049a747e4fSDavid du Colombier kstrdup(&p->user, up->user); 2053e12c5d1SDavid du Colombier /* 2063e12c5d1SDavid du Colombier * since the bss/data segments are now shareable, 2073e12c5d1SDavid du Colombier * any mmu info about this process is now stale 2083e12c5d1SDavid du Colombier * (i.e. has bad properties) and has to be discarded. 2093e12c5d1SDavid du Colombier */ 2103e12c5d1SDavid du Colombier flushmmu(); 2117dd7cddfSDavid du Colombier p->basepri = up->basepri; 2129a747e4fSDavid du Colombier p->priority = up->basepri; 21380ee5cbfSDavid du Colombier p->fixedpri = up->fixedpri; 2147dd7cddfSDavid du Colombier p->mp = up->mp; 2157dd7cddfSDavid du Colombier wm = up->wired; 2167dd7cddfSDavid du Colombier if(wm) 2177dd7cddfSDavid du Colombier procwired(p, wm->machno); 2183e12c5d1SDavid du Colombier ready(p); 219219b2ee8SDavid du Colombier sched(); 2203e12c5d1SDavid du Colombier return pid; 2213e12c5d1SDavid du Colombier } 2223e12c5d1SDavid du Colombier 2233e12c5d1SDavid du Colombier static ulong 2243e12c5d1SDavid du Colombier l2be(long l) 2253e12c5d1SDavid du Colombier { 2263e12c5d1SDavid du Colombier uchar *cp; 2273e12c5d1SDavid du Colombier 2283e12c5d1SDavid du Colombier cp = (uchar*)&l; 2293e12c5d1SDavid du Colombier return (cp[0]<<24) | (cp[1]<<16) | (cp[2]<<8) | cp[3]; 2303e12c5d1SDavid du Colombier } 2313e12c5d1SDavid du Colombier 2323e12c5d1SDavid du Colombier long 2333e12c5d1SDavid du Colombier sysexec(ulong *arg) 2343e12c5d1SDavid du Colombier { 2353e12c5d1SDavid du Colombier Segment *s, *ts; 2363e12c5d1SDavid du Colombier ulong t, d, b; 2373e12c5d1SDavid du Colombier int i; 2383e12c5d1SDavid du Colombier Chan *tc; 2393e12c5d1SDavid du Colombier char **argv, **argp; 2409a747e4fSDavid du Colombier char *a, *charp, *args, *file; 2419a747e4fSDavid du Colombier char *progarg[sizeof(Exec)/2+1], *elem, progelem[64]; 2423e12c5d1SDavid du Colombier ulong ssize, spage, nargs, nbytes, n, bssend; 2433e12c5d1SDavid du Colombier int indir; 2443e12c5d1SDavid du Colombier Exec exec; 2453e12c5d1SDavid du Colombier char line[sizeof(Exec)]; 2463e12c5d1SDavid du Colombier Fgrp *f; 2473e12c5d1SDavid du Colombier Image *img; 2483e12c5d1SDavid du Colombier ulong magic, text, entry, data, bss; 2493e12c5d1SDavid du Colombier 2503e12c5d1SDavid du Colombier validaddr(arg[0], 1, 0); 2513e12c5d1SDavid du Colombier file = (char*)arg[0]; 2523e12c5d1SDavid du Colombier indir = 0; 2539a747e4fSDavid du Colombier elem = nil; 2549a747e4fSDavid du Colombier if(waserror()){ 2559a747e4fSDavid du Colombier free(elem); 2569a747e4fSDavid du Colombier nexterror(); 2579a747e4fSDavid du Colombier } 2587dd7cddfSDavid du Colombier for(;;){ 2593e12c5d1SDavid du Colombier tc = namec(file, Aopen, OEXEC, 0); 2603e12c5d1SDavid du Colombier if(waserror()){ 2617dd7cddfSDavid du Colombier cclose(tc); 2623e12c5d1SDavid du Colombier nexterror(); 2633e12c5d1SDavid du Colombier } 2643e12c5d1SDavid du Colombier if(!indir) 2659a747e4fSDavid du Colombier kstrdup(&elem, up->genbuf); 2663e12c5d1SDavid du Colombier 2677dd7cddfSDavid du Colombier n = devtab[tc->type]->read(tc, &exec, sizeof(Exec), 0); 2683e12c5d1SDavid du Colombier if(n < 2) 2693e12c5d1SDavid du Colombier error(Ebadexec); 2703e12c5d1SDavid du Colombier magic = l2be(exec.magic); 2713e12c5d1SDavid du Colombier text = l2be(exec.text); 2723e12c5d1SDavid du Colombier entry = l2be(exec.entry); 2737dd7cddfSDavid du Colombier if(n==sizeof(Exec) && (magic == AOUT_MAGIC)){ 27459cc4ca5SDavid du Colombier if((text&KZERO) == KZERO 2753e12c5d1SDavid du Colombier || entry < UTZERO+sizeof(Exec) 2763e12c5d1SDavid du Colombier || entry >= UTZERO+sizeof(Exec)+text) 2777dd7cddfSDavid du Colombier error(Ebadexec); 2787dd7cddfSDavid du Colombier break; /* for binary */ 2793e12c5d1SDavid du Colombier } 2803e12c5d1SDavid du Colombier 2813e12c5d1SDavid du Colombier /* 2823e12c5d1SDavid du Colombier * Process #! /bin/sh args ... 2833e12c5d1SDavid du Colombier */ 2843e12c5d1SDavid du Colombier memmove(line, &exec, sizeof(Exec)); 2853e12c5d1SDavid du Colombier if(indir || line[0]!='#' || line[1]!='!') 2867dd7cddfSDavid du Colombier error(Ebadexec); 2873e12c5d1SDavid du Colombier n = shargs(line, n, progarg); 2883e12c5d1SDavid du Colombier if(n == 0) 2897dd7cddfSDavid du Colombier error(Ebadexec); 2903e12c5d1SDavid du Colombier indir = 1; 2913e12c5d1SDavid du Colombier /* 2923e12c5d1SDavid du Colombier * First arg becomes complete file name 2933e12c5d1SDavid du Colombier */ 2943e12c5d1SDavid du Colombier progarg[n++] = file; 2953e12c5d1SDavid du Colombier progarg[n] = 0; 2963e12c5d1SDavid du Colombier validaddr(arg[1], BY2WD, 1); 2973e12c5d1SDavid du Colombier arg[1] += BY2WD; 2983e12c5d1SDavid du Colombier file = progarg[0]; 2999a747e4fSDavid du Colombier if(strlen(elem) >= sizeof progelem) 3009a747e4fSDavid du Colombier error(Ebadexec); 3019a747e4fSDavid du Colombier strcpy(progelem, elem); 3029a747e4fSDavid du Colombier progarg[0] = progelem; 3033e12c5d1SDavid du Colombier poperror(); 3047dd7cddfSDavid du Colombier cclose(tc); 3057dd7cddfSDavid du Colombier } 3063e12c5d1SDavid du Colombier 3073e12c5d1SDavid du Colombier data = l2be(exec.data); 3083e12c5d1SDavid du Colombier bss = l2be(exec.bss); 3093e12c5d1SDavid du Colombier t = (UTZERO+sizeof(Exec)+text+(BY2PG-1)) & ~(BY2PG-1); 3103e12c5d1SDavid du Colombier d = (t + data + (BY2PG-1)) & ~(BY2PG-1); 3113e12c5d1SDavid du Colombier bssend = t + data + bss; 3123e12c5d1SDavid du Colombier b = (bssend + (BY2PG-1)) & ~(BY2PG-1); 31359cc4ca5SDavid du Colombier if(((t|d|b) & KZERO) == KZERO) 3143e12c5d1SDavid du Colombier error(Ebadexec); 3153e12c5d1SDavid du Colombier 3163e12c5d1SDavid du Colombier /* 3173e12c5d1SDavid du Colombier * Args: pass 1: count 3183e12c5d1SDavid du Colombier */ 3193e12c5d1SDavid du Colombier nbytes = BY2WD; /* hole for profiling clock at top of stack */ 3203e12c5d1SDavid du Colombier nargs = 0; 3213e12c5d1SDavid du Colombier if(indir){ 3223e12c5d1SDavid du Colombier argp = progarg; 3233e12c5d1SDavid du Colombier while(*argp){ 3243e12c5d1SDavid du Colombier a = *argp++; 3253e12c5d1SDavid du Colombier nbytes += strlen(a) + 1; 3263e12c5d1SDavid du Colombier nargs++; 3273e12c5d1SDavid du Colombier } 3283e12c5d1SDavid du Colombier } 3293e12c5d1SDavid du Colombier evenaddr(arg[1]); 3303e12c5d1SDavid du Colombier argp = (char**)arg[1]; 3313e12c5d1SDavid du Colombier validaddr((ulong)argp, BY2WD, 0); 3323e12c5d1SDavid du Colombier while(*argp){ 3333e12c5d1SDavid du Colombier a = *argp++; 3343e12c5d1SDavid du Colombier if(((ulong)argp&(BY2PG-1)) < BY2WD) 3353e12c5d1SDavid du Colombier validaddr((ulong)argp, BY2WD, 0); 3363e12c5d1SDavid du Colombier validaddr((ulong)a, 1, 0); 337219b2ee8SDavid du Colombier nbytes += (vmemchr(a, 0, 0x7FFFFFFF) - a) + 1; 3383e12c5d1SDavid du Colombier nargs++; 3393e12c5d1SDavid du Colombier } 3403e12c5d1SDavid du Colombier ssize = BY2WD*(nargs+1) + ((nbytes+(BY2WD-1)) & ~(BY2WD-1)); 341bd389b36SDavid du Colombier 3423e12c5d1SDavid du Colombier /* 3433e12c5d1SDavid du Colombier * 8-byte align SP for those (e.g. sparc) that need it. 3443e12c5d1SDavid du Colombier * execregs() will subtract another 4 bytes for argc. 3453e12c5d1SDavid du Colombier */ 3463e12c5d1SDavid du Colombier if((ssize+4) & 7) 3473e12c5d1SDavid du Colombier ssize += 4; 3483e12c5d1SDavid du Colombier spage = (ssize+(BY2PG-1)) >> PGSHIFT; 3497dd7cddfSDavid du Colombier 3503e12c5d1SDavid du Colombier /* 3513e12c5d1SDavid du Colombier * Build the stack segment, putting it in kernel virtual for the moment 3523e12c5d1SDavid du Colombier */ 3533e12c5d1SDavid du Colombier if(spage > TSTKSIZ) 3543e12c5d1SDavid du Colombier error(Enovmem); 3553e12c5d1SDavid du Colombier 3567dd7cddfSDavid du Colombier qlock(&up->seglock); 3577dd7cddfSDavid du Colombier if(waserror()){ 3587dd7cddfSDavid du Colombier qunlock(&up->seglock); 3597dd7cddfSDavid du Colombier nexterror(); 3607dd7cddfSDavid du Colombier } 3617dd7cddfSDavid du Colombier up->seg[ESEG] = newseg(SG_STACK, TSTKTOP-USTKSIZE, USTKSIZE/BY2PG); 3623e12c5d1SDavid du Colombier 3633e12c5d1SDavid du Colombier /* 3643e12c5d1SDavid du Colombier * Args: pass 2: assemble; the pages will be faulted in 3653e12c5d1SDavid du Colombier */ 3663e12c5d1SDavid du Colombier argv = (char**)(TSTKTOP - ssize); 3673e12c5d1SDavid du Colombier charp = (char*)(TSTKTOP - nbytes); 3689a747e4fSDavid du Colombier args = charp; 3693e12c5d1SDavid du Colombier if(indir) 3703e12c5d1SDavid du Colombier argp = progarg; 3713e12c5d1SDavid du Colombier else 3723e12c5d1SDavid du Colombier argp = (char**)arg[1]; 3733e12c5d1SDavid du Colombier 3743e12c5d1SDavid du Colombier for(i=0; i<nargs; i++){ 3753e12c5d1SDavid du Colombier if(indir && *argp==0) { 3763e12c5d1SDavid du Colombier indir = 0; 3773e12c5d1SDavid du Colombier argp = (char**)arg[1]; 3783e12c5d1SDavid du Colombier } 3793e12c5d1SDavid du Colombier *argv++ = charp + (USTKTOP-TSTKTOP); 3803e12c5d1SDavid du Colombier n = strlen(*argp) + 1; 3813e12c5d1SDavid du Colombier memmove(charp, *argp++, n); 3823e12c5d1SDavid du Colombier charp += n; 3833e12c5d1SDavid du Colombier } 3843e12c5d1SDavid du Colombier 3859a747e4fSDavid du Colombier free(up->text); 3869a747e4fSDavid du Colombier up->text = elem; 3879a747e4fSDavid du Colombier elem = nil; /* so waserror() won't free elem */ 3889a747e4fSDavid du Colombier USED(elem); 3899a747e4fSDavid du Colombier 3909a747e4fSDavid du Colombier /* copy args; easiest from new process's stack */ 3919a747e4fSDavid du Colombier n = charp - args; 3929a747e4fSDavid du Colombier if(n > 128) /* don't waste too much space on huge arg lists */ 3939a747e4fSDavid du Colombier n = 128; 3949a747e4fSDavid du Colombier a = up->args; 3959a747e4fSDavid du Colombier up->args = nil; 3969a747e4fSDavid du Colombier free(a); 3979a747e4fSDavid du Colombier up->args = smalloc(n); 3989a747e4fSDavid du Colombier memmove(up->args, args, n); 3999a747e4fSDavid du Colombier if(n>0 && up->args[n-1]!='\0'){ 4009a747e4fSDavid du Colombier /* make sure last arg is NUL-terminated */ 4019a747e4fSDavid du Colombier /* put NUL at UTF-8 character boundary */ 4029a747e4fSDavid du Colombier for(i=n-1; i>0; --i) 4039a747e4fSDavid du Colombier if(fullrune(up->args+i, n-i)) 4049a747e4fSDavid du Colombier break; 4059a747e4fSDavid du Colombier up->args[i] = 0; 4069a747e4fSDavid du Colombier n = i+1; 4079a747e4fSDavid du Colombier } 4089a747e4fSDavid du Colombier up->nargs = n; 4093e12c5d1SDavid du Colombier 4103e12c5d1SDavid du Colombier /* 411bd389b36SDavid du Colombier * Committed. 412bd389b36SDavid du Colombier * Free old memory. 4137dd7cddfSDavid du Colombier * Special segments are maintained across exec 4143e12c5d1SDavid du Colombier */ 4153e12c5d1SDavid du Colombier for(i = SSEG; i <= BSEG; i++) { 4167dd7cddfSDavid du Colombier putseg(up->seg[i]); 417219b2ee8SDavid du Colombier /* prevent a second free if we have an error */ 4187dd7cddfSDavid du Colombier up->seg[i] = 0; 419219b2ee8SDavid du Colombier } 420219b2ee8SDavid du Colombier for(i = BSEG+1; i < NSEG; i++) { 4217dd7cddfSDavid du Colombier s = up->seg[i]; 422219b2ee8SDavid du Colombier if(s != 0 && (s->type&SG_CEXEC)) { 423219b2ee8SDavid du Colombier putseg(s); 4247dd7cddfSDavid du Colombier up->seg[i] = 0; 425219b2ee8SDavid du Colombier } 4263e12c5d1SDavid du Colombier } 4273e12c5d1SDavid du Colombier 4283e12c5d1SDavid du Colombier /* 4293e12c5d1SDavid du Colombier * Close on exec 4303e12c5d1SDavid du Colombier */ 4317dd7cddfSDavid du Colombier f = up->fgrp; 4323e12c5d1SDavid du Colombier for(i=0; i<=f->maxfd; i++) 4333e12c5d1SDavid du Colombier fdclose(i, CCEXEC); 4343e12c5d1SDavid du Colombier 4353e12c5d1SDavid du Colombier /* Text. Shared. Attaches to cache image if possible */ 4363e12c5d1SDavid du Colombier /* attachimage returns a locked cache image */ 4373e12c5d1SDavid du Colombier img = attachimage(SG_TEXT|SG_RONLY, tc, UTZERO, (t-UTZERO)>>PGSHIFT); 4383e12c5d1SDavid du Colombier ts = img->s; 4397dd7cddfSDavid du Colombier up->seg[TSEG] = ts; 4403e12c5d1SDavid du Colombier ts->flushme = 1; 4413e12c5d1SDavid du Colombier ts->fstart = 0; 4423e12c5d1SDavid du Colombier ts->flen = sizeof(Exec)+text; 4433e12c5d1SDavid du Colombier unlock(img); 4443e12c5d1SDavid du Colombier 4453e12c5d1SDavid du Colombier /* Data. Shared. */ 4463e12c5d1SDavid du Colombier s = newseg(SG_DATA, t, (d-t)>>PGSHIFT); 4477dd7cddfSDavid du Colombier up->seg[DSEG] = s; 4483e12c5d1SDavid du Colombier 4493e12c5d1SDavid du Colombier /* Attached by hand */ 4503e12c5d1SDavid du Colombier incref(img); 4513e12c5d1SDavid du Colombier s->image = img; 4523e12c5d1SDavid du Colombier s->fstart = ts->fstart+ts->flen; 4533e12c5d1SDavid du Colombier s->flen = data; 4543e12c5d1SDavid du Colombier 4553e12c5d1SDavid du Colombier /* BSS. Zero fill on demand */ 4567dd7cddfSDavid du Colombier up->seg[BSEG] = newseg(SG_BSS, d, (b-d)>>PGSHIFT); 4573e12c5d1SDavid du Colombier 4583e12c5d1SDavid du Colombier /* 4593e12c5d1SDavid du Colombier * Move the stack 4603e12c5d1SDavid du Colombier */ 4617dd7cddfSDavid du Colombier s = up->seg[ESEG]; 4627dd7cddfSDavid du Colombier up->seg[ESEG] = 0; 4637dd7cddfSDavid du Colombier up->seg[SSEG] = s; 4647dd7cddfSDavid du Colombier qunlock(&up->seglock); 4659a747e4fSDavid du Colombier poperror(); /* seglock */ 4669a747e4fSDavid du Colombier poperror(); /* elem */ 4673e12c5d1SDavid du Colombier s->base = USTKTOP-USTKSIZE; 4683e12c5d1SDavid du Colombier s->top = USTKTOP; 4697dd7cddfSDavid du Colombier relocateseg(s, USTKTOP-TSTKTOP); 4703e12c5d1SDavid du Colombier 471219b2ee8SDavid du Colombier /* 472219b2ee8SDavid du Colombier * '/' processes are higher priority (hack to make /ip more responsive). 473219b2ee8SDavid du Colombier */ 4747dd7cddfSDavid du Colombier if(devtab[tc->type]->dc == L'/') 4757dd7cddfSDavid du Colombier up->basepri = PriRoot; 4767dd7cddfSDavid du Colombier up->priority = up->basepri; 4777dd7cddfSDavid du Colombier poperror(); 4787dd7cddfSDavid du Colombier cclose(tc); 4793e12c5d1SDavid du Colombier 4803e12c5d1SDavid du Colombier /* 4813e12c5d1SDavid du Colombier * At this point, the mmu contains info about the old address 4823e12c5d1SDavid du Colombier * space and needs to be flushed 4833e12c5d1SDavid du Colombier */ 4843e12c5d1SDavid du Colombier flushmmu(); 4857dd7cddfSDavid du Colombier qlock(&up->debug); 4867dd7cddfSDavid du Colombier up->nnote = 0; 4877dd7cddfSDavid du Colombier up->notify = 0; 4887dd7cddfSDavid du Colombier up->notified = 0; 4899a747e4fSDavid du Colombier up->privatemem = 0; 4907dd7cddfSDavid du Colombier procsetup(up); 4917dd7cddfSDavid du Colombier qunlock(&up->debug); 4927dd7cddfSDavid du Colombier if(up->hang) 4937dd7cddfSDavid du Colombier up->procctl = Proc_stopme; 4943e12c5d1SDavid du Colombier 4953e12c5d1SDavid du Colombier return execregs(entry, ssize, nargs); 4963e12c5d1SDavid du Colombier } 4973e12c5d1SDavid du Colombier 4983e12c5d1SDavid du Colombier int 4993e12c5d1SDavid du Colombier shargs(char *s, int n, char **ap) 5003e12c5d1SDavid du Colombier { 5013e12c5d1SDavid du Colombier int i; 5023e12c5d1SDavid du Colombier 503bd389b36SDavid du Colombier s += 2; 504bd389b36SDavid du Colombier n -= 2; /* skip #! */ 5053e12c5d1SDavid du Colombier for(i=0; s[i]!='\n'; i++) 5063e12c5d1SDavid du Colombier if(i == n-1) 5073e12c5d1SDavid du Colombier return 0; 5083e12c5d1SDavid du Colombier s[i] = 0; 5093e12c5d1SDavid du Colombier *ap = 0; 5103e12c5d1SDavid du Colombier i = 0; 5113e12c5d1SDavid du Colombier for(;;) { 5123e12c5d1SDavid du Colombier while(*s==' ' || *s=='\t') 5133e12c5d1SDavid du Colombier s++; 5143e12c5d1SDavid du Colombier if(*s == 0) 5153e12c5d1SDavid du Colombier break; 5163e12c5d1SDavid du Colombier i++; 5173e12c5d1SDavid du Colombier *ap++ = s; 5183e12c5d1SDavid du Colombier *ap = 0; 5193e12c5d1SDavid du Colombier while(*s && *s!=' ' && *s!='\t') 5203e12c5d1SDavid du Colombier s++; 5213e12c5d1SDavid du Colombier if(*s == 0) 5223e12c5d1SDavid du Colombier break; 5233e12c5d1SDavid du Colombier else 5243e12c5d1SDavid du Colombier *s++ = 0; 5253e12c5d1SDavid du Colombier } 5263e12c5d1SDavid du Colombier return i; 5273e12c5d1SDavid du Colombier } 5283e12c5d1SDavid du Colombier 5293e12c5d1SDavid du Colombier int 5307dd7cddfSDavid du Colombier return0(void*) 5313e12c5d1SDavid du Colombier { 5323e12c5d1SDavid du Colombier return 0; 5333e12c5d1SDavid du Colombier } 5343e12c5d1SDavid du Colombier 5353e12c5d1SDavid du Colombier long 5363e12c5d1SDavid du Colombier syssleep(ulong *arg) 5373e12c5d1SDavid du Colombier { 5387dd7cddfSDavid du Colombier 539219b2ee8SDavid du Colombier int n; 540219b2ee8SDavid du Colombier 541219b2ee8SDavid du Colombier n = arg[0]; 5427dd7cddfSDavid du Colombier if(n <= 0) { 543*bd2ae673SDavid du Colombier yield(); 544219b2ee8SDavid du Colombier return 0; 545219b2ee8SDavid du Colombier } 5467dd7cddfSDavid du Colombier if(n < TK2MS(1)) 547219b2ee8SDavid du Colombier n = TK2MS(1); 5487dd7cddfSDavid du Colombier tsleep(&up->sleep, return0, 0, n); 5493e12c5d1SDavid du Colombier return 0; 5503e12c5d1SDavid du Colombier } 5513e12c5d1SDavid du Colombier 5523e12c5d1SDavid du Colombier long 5533e12c5d1SDavid du Colombier sysalarm(ulong *arg) 5543e12c5d1SDavid du Colombier { 5553e12c5d1SDavid du Colombier return procalarm(arg[0]); 5563e12c5d1SDavid du Colombier } 5573e12c5d1SDavid du Colombier 5583e12c5d1SDavid du Colombier long 5593e12c5d1SDavid du Colombier sysexits(ulong *arg) 5603e12c5d1SDavid du Colombier { 5613e12c5d1SDavid du Colombier char *status; 5623e12c5d1SDavid du Colombier char *inval = "invalid exit string"; 5639a747e4fSDavid du Colombier char buf[ERRMAX]; 5643e12c5d1SDavid du Colombier 5653e12c5d1SDavid du Colombier status = (char*)arg[0]; 5663e12c5d1SDavid du Colombier if(status){ 5673e12c5d1SDavid du Colombier if(waserror()) 5683e12c5d1SDavid du Colombier status = inval; 5693e12c5d1SDavid du Colombier else{ 5703e12c5d1SDavid du Colombier validaddr((ulong)status, 1, 0); 5719a747e4fSDavid du Colombier if(vmemchr(status, 0, ERRMAX) == 0){ 5729a747e4fSDavid du Colombier memmove(buf, status, ERRMAX); 5739a747e4fSDavid du Colombier buf[ERRMAX-1] = 0; 574219b2ee8SDavid du Colombier status = buf; 575219b2ee8SDavid du Colombier } 5763e12c5d1SDavid du Colombier } 5773e12c5d1SDavid du Colombier poperror(); 5783e12c5d1SDavid du Colombier 5793e12c5d1SDavid du Colombier } 5803e12c5d1SDavid du Colombier pexit(status, 1); 5813e12c5d1SDavid du Colombier return 0; /* not reached */ 5823e12c5d1SDavid du Colombier } 5833e12c5d1SDavid du Colombier 5843e12c5d1SDavid du Colombier long 5859a747e4fSDavid du Colombier sys_wait(ulong *arg) 5863e12c5d1SDavid du Colombier { 5879a747e4fSDavid du Colombier int pid; 5889a747e4fSDavid du Colombier Waitmsg w; 5899a747e4fSDavid du Colombier OWaitmsg *ow; 5909a747e4fSDavid du Colombier 5919a747e4fSDavid du Colombier if(arg[0] == 0) 5929a747e4fSDavid du Colombier return pwait(nil); 5939a747e4fSDavid du Colombier 5949a747e4fSDavid du Colombier validaddr(arg[0], sizeof(OWaitmsg), 1); 5953e12c5d1SDavid du Colombier evenaddr(arg[0]); 5969a747e4fSDavid du Colombier pid = pwait(&w); 5979a747e4fSDavid du Colombier if(pid >= 0){ 5989a747e4fSDavid du Colombier ow = (OWaitmsg*)arg[0]; 5999a747e4fSDavid du Colombier readnum(0, ow->pid, NUMSIZE, w.pid, NUMSIZE); 6009a747e4fSDavid du Colombier readnum(0, ow->time+TUser*NUMSIZE, NUMSIZE, w.time[TUser], NUMSIZE); 6019a747e4fSDavid du Colombier readnum(0, ow->time+TSys*NUMSIZE, NUMSIZE, w.time[TSys], NUMSIZE); 6029a747e4fSDavid du Colombier readnum(0, ow->time+TReal*NUMSIZE, NUMSIZE, w.time[TReal], NUMSIZE); 6039a747e4fSDavid du Colombier strncpy(ow->msg, w.msg, sizeof(ow->msg)); 6049a747e4fSDavid du Colombier ow->msg[sizeof(ow->msg)-1] = '\0'; 6053e12c5d1SDavid du Colombier } 6069a747e4fSDavid du Colombier return pid; 6079a747e4fSDavid du Colombier } 6089a747e4fSDavid du Colombier 6099a747e4fSDavid du Colombier long 6109a747e4fSDavid du Colombier sysawait(ulong *arg) 6119a747e4fSDavid du Colombier { 6129a747e4fSDavid du Colombier int i; 6139a747e4fSDavid du Colombier int pid; 6149a747e4fSDavid du Colombier Waitmsg w; 6159a747e4fSDavid du Colombier ulong n; 6169a747e4fSDavid du Colombier 6179a747e4fSDavid du Colombier n = arg[1]; 6189a747e4fSDavid du Colombier validaddr(arg[0], n, 1); 6199a747e4fSDavid du Colombier pid = pwait(&w); 6209a747e4fSDavid du Colombier if(pid < 0) 6219a747e4fSDavid du Colombier return -1; 6229a747e4fSDavid du Colombier i = snprint((char*)arg[0], n, "%d %lud %lud %lud %q", 6239a747e4fSDavid du Colombier w.pid, 6249a747e4fSDavid du Colombier w.time[TUser], w.time[TSys], w.time[TReal], 6259a747e4fSDavid du Colombier w.msg); 6269a747e4fSDavid du Colombier 6279a747e4fSDavid du Colombier return i; 6283e12c5d1SDavid du Colombier } 6293e12c5d1SDavid du Colombier 6303e12c5d1SDavid du Colombier long 6317dd7cddfSDavid du Colombier sysdeath(ulong*) 6323e12c5d1SDavid du Colombier { 6333e12c5d1SDavid du Colombier pprint("deprecated system call\n"); 6343e12c5d1SDavid du Colombier pexit("Suicide", 0); 6353e12c5d1SDavid du Colombier return 0; /* not reached */ 6363e12c5d1SDavid du Colombier } 6373e12c5d1SDavid du Colombier 6387dd7cddfSDavid du Colombier void 6397dd7cddfSDavid du Colombier werrstr(char *fmt, ...) 6407dd7cddfSDavid du Colombier { 6417dd7cddfSDavid du Colombier va_list va; 6427dd7cddfSDavid du Colombier 6437dd7cddfSDavid du Colombier if(up == nil) 6447dd7cddfSDavid du Colombier return; 6457dd7cddfSDavid du Colombier 6467dd7cddfSDavid du Colombier va_start(va, fmt); 6479a747e4fSDavid du Colombier vseprint(up->syserrstr, up->syserrstr+ERRMAX, fmt, va); 6487dd7cddfSDavid du Colombier va_end(va); 6497dd7cddfSDavid du Colombier } 6507dd7cddfSDavid du Colombier 6519a747e4fSDavid du Colombier static long 6529a747e4fSDavid du Colombier generrstr(char *buf, uint nbuf) 6539a747e4fSDavid du Colombier { 6549a747e4fSDavid du Colombier char tmp[ERRMAX]; 6559a747e4fSDavid du Colombier 6569a747e4fSDavid du Colombier if(nbuf == 0) 6579a747e4fSDavid du Colombier error(Ebadarg); 6589a747e4fSDavid du Colombier validaddr((ulong)buf, nbuf, 1); 6599a747e4fSDavid du Colombier if(nbuf > sizeof tmp) 6609a747e4fSDavid du Colombier nbuf = sizeof tmp; 6619a747e4fSDavid du Colombier memmove(tmp, buf, nbuf); 6629a747e4fSDavid du Colombier /* make sure it's NUL-terminated */ 6639a747e4fSDavid du Colombier tmp[nbuf-1] = '\0'; 6649a747e4fSDavid du Colombier memmove(buf, up->syserrstr, nbuf); 6659a747e4fSDavid du Colombier buf[nbuf-1] = '\0'; 6669a747e4fSDavid du Colombier memmove(up->syserrstr, tmp, nbuf); 6679a747e4fSDavid du Colombier return 0; 6689a747e4fSDavid du Colombier } 6699a747e4fSDavid du Colombier 6703e12c5d1SDavid du Colombier long 6713e12c5d1SDavid du Colombier syserrstr(ulong *arg) 6723e12c5d1SDavid du Colombier { 6739a747e4fSDavid du Colombier return generrstr((char*)arg[0], arg[1]); 6749a747e4fSDavid du Colombier } 675219b2ee8SDavid du Colombier 6769a747e4fSDavid du Colombier /* compatibility for old binaries */ 6779a747e4fSDavid du Colombier long 6789a747e4fSDavid du Colombier sys_errstr(ulong *arg) 6799a747e4fSDavid du Colombier { 6809a747e4fSDavid du Colombier return generrstr((char*)arg[0], 64); 6813e12c5d1SDavid du Colombier } 6823e12c5d1SDavid du Colombier 6833e12c5d1SDavid du Colombier long 6843e12c5d1SDavid du Colombier sysnotify(ulong *arg) 6853e12c5d1SDavid du Colombier { 6863e12c5d1SDavid du Colombier if(arg[0] != 0) 6873e12c5d1SDavid du Colombier validaddr(arg[0], sizeof(ulong), 0); 6887dd7cddfSDavid du Colombier up->notify = (int(*)(void*, char*))(arg[0]); 6893e12c5d1SDavid du Colombier return 0; 6903e12c5d1SDavid du Colombier } 6913e12c5d1SDavid du Colombier 6923e12c5d1SDavid du Colombier long 6933e12c5d1SDavid du Colombier sysnoted(ulong *arg) 6943e12c5d1SDavid du Colombier { 6957dd7cddfSDavid du Colombier if(arg[0]!=NRSTR && !up->notified) 6963e12c5d1SDavid du Colombier error(Egreg); 6973e12c5d1SDavid du Colombier return 0; 6983e12c5d1SDavid du Colombier } 6993e12c5d1SDavid du Colombier 7003e12c5d1SDavid du Colombier long 7013e12c5d1SDavid du Colombier syssegbrk(ulong *arg) 7023e12c5d1SDavid du Colombier { 7033e12c5d1SDavid du Colombier int i; 7047dd7cddfSDavid du Colombier ulong addr; 7057dd7cddfSDavid du Colombier Segment *s; 7063e12c5d1SDavid du Colombier 7077dd7cddfSDavid du Colombier addr = arg[0]; 708219b2ee8SDavid du Colombier for(i = 0; i < NSEG; i++) { 7097dd7cddfSDavid du Colombier s = up->seg[i]; 7107dd7cddfSDavid du Colombier if(s == 0 || addr < s->base || addr >= s->top) 7117dd7cddfSDavid du Colombier continue; 7123e12c5d1SDavid du Colombier switch(s->type&SG_TYPE) { 7133e12c5d1SDavid du Colombier case SG_TEXT: 7143e12c5d1SDavid du Colombier case SG_DATA: 715219b2ee8SDavid du Colombier case SG_STACK: 7163e12c5d1SDavid du Colombier error(Ebadarg); 7173e12c5d1SDavid du Colombier default: 7183e12c5d1SDavid du Colombier return ibrk(arg[1], i); 7193e12c5d1SDavid du Colombier } 7203e12c5d1SDavid du Colombier } 7213e12c5d1SDavid du Colombier 7223e12c5d1SDavid du Colombier error(Ebadarg); 7233e12c5d1SDavid du Colombier return 0; /* not reached */ 7243e12c5d1SDavid du Colombier } 7253e12c5d1SDavid du Colombier 7263e12c5d1SDavid du Colombier long 7273e12c5d1SDavid du Colombier syssegattach(ulong *arg) 7283e12c5d1SDavid du Colombier { 7297dd7cddfSDavid du Colombier return segattach(up, arg[0], (char*)arg[1], arg[2], arg[3]); 7303e12c5d1SDavid du Colombier } 7313e12c5d1SDavid du Colombier 7323e12c5d1SDavid du Colombier long 7333e12c5d1SDavid du Colombier syssegdetach(ulong *arg) 7343e12c5d1SDavid du Colombier { 7353e12c5d1SDavid du Colombier int i; 7367dd7cddfSDavid du Colombier ulong addr; 7373e12c5d1SDavid du Colombier Segment *s; 7383e12c5d1SDavid du Colombier 7397dd7cddfSDavid du Colombier qlock(&up->seglock); 7407dd7cddfSDavid du Colombier if(waserror()){ 7417dd7cddfSDavid du Colombier qunlock(&up->seglock); 7427dd7cddfSDavid du Colombier nexterror(); 7437dd7cddfSDavid du Colombier } 7447dd7cddfSDavid du Colombier 7453e12c5d1SDavid du Colombier s = 0; 7467dd7cddfSDavid du Colombier addr = arg[0]; 7473e12c5d1SDavid du Colombier for(i = 0; i < NSEG; i++) 7487dd7cddfSDavid du Colombier if(s = up->seg[i]) { 7493e12c5d1SDavid du Colombier qlock(&s->lk); 7507dd7cddfSDavid du Colombier if((addr >= s->base && addr < s->top) || 7517dd7cddfSDavid du Colombier (s->top == s->base && addr == s->base)) 7523e12c5d1SDavid du Colombier goto found; 7533e12c5d1SDavid du Colombier qunlock(&s->lk); 7543e12c5d1SDavid du Colombier } 7553e12c5d1SDavid du Colombier 7563e12c5d1SDavid du Colombier error(Ebadarg); 7573e12c5d1SDavid du Colombier 7583e12c5d1SDavid du Colombier found: 7597dd7cddfSDavid du Colombier /* Check we are not detaching the current stack segment */ 7603e12c5d1SDavid du Colombier if((ulong)arg >= s->base && (ulong)arg < s->top) { 7613e12c5d1SDavid du Colombier qunlock(&s->lk); 7623e12c5d1SDavid du Colombier error(Ebadarg); 7633e12c5d1SDavid du Colombier } 7647dd7cddfSDavid du Colombier up->seg[i] = 0; 7653e12c5d1SDavid du Colombier qunlock(&s->lk); 7663e12c5d1SDavid du Colombier putseg(s); 7677dd7cddfSDavid du Colombier qunlock(&up->seglock); 7687dd7cddfSDavid du Colombier poperror(); 7693e12c5d1SDavid du Colombier 7703e12c5d1SDavid du Colombier /* Ensure we flush any entries from the lost segment */ 7713e12c5d1SDavid du Colombier flushmmu(); 7723e12c5d1SDavid du Colombier return 0; 7733e12c5d1SDavid du Colombier } 7743e12c5d1SDavid du Colombier 7753e12c5d1SDavid du Colombier long 7763e12c5d1SDavid du Colombier syssegfree(ulong *arg) 7773e12c5d1SDavid du Colombier { 7783e12c5d1SDavid du Colombier Segment *s; 7799a747e4fSDavid du Colombier ulong from, to; 7803e12c5d1SDavid du Colombier 7819a747e4fSDavid du Colombier from = arg[0]; 7827dd7cddfSDavid du Colombier s = seg(up, from, 1); 7839a747e4fSDavid du Colombier if(s == nil) 7843e12c5d1SDavid du Colombier error(Ebadarg); 7859a747e4fSDavid du Colombier to = (from + arg[1]) & ~(BY2PG-1); 7869a747e4fSDavid du Colombier from = PGROUND(from); 7873e12c5d1SDavid du Colombier 7889a747e4fSDavid du Colombier if(to > s->top) { 7893e12c5d1SDavid du Colombier qunlock(&s->lk); 7903e12c5d1SDavid du Colombier error(Ebadarg); 7913e12c5d1SDavid du Colombier } 7923e12c5d1SDavid du Colombier 7939a747e4fSDavid du Colombier mfreeseg(s, from, (to - from) / BY2PG); 7943e12c5d1SDavid du Colombier qunlock(&s->lk); 795bd389b36SDavid du Colombier flushmmu(); 7963e12c5d1SDavid du Colombier 7973e12c5d1SDavid du Colombier return 0; 7983e12c5d1SDavid du Colombier } 7993e12c5d1SDavid du Colombier 8007dd7cddfSDavid du Colombier /* For binary compatibility */ 8013e12c5d1SDavid du Colombier long 8023e12c5d1SDavid du Colombier sysbrk_(ulong *arg) 8033e12c5d1SDavid du Colombier { 8043e12c5d1SDavid du Colombier return ibrk(arg[0], BSEG); 8053e12c5d1SDavid du Colombier } 8063e12c5d1SDavid du Colombier 8073e12c5d1SDavid du Colombier long 8083e12c5d1SDavid du Colombier sysrendezvous(ulong *arg) 8093e12c5d1SDavid du Colombier { 8107dd7cddfSDavid du Colombier ulong tag; 8113e12c5d1SDavid du Colombier ulong val; 8127dd7cddfSDavid du Colombier Proc *p, **l; 8133e12c5d1SDavid du Colombier 8143e12c5d1SDavid du Colombier tag = arg[0]; 8157dd7cddfSDavid du Colombier l = &REND(up->rgrp, tag); 8169a747e4fSDavid du Colombier up->rendval = ~0UL; 8173e12c5d1SDavid du Colombier 8187dd7cddfSDavid du Colombier lock(up->rgrp); 8193e12c5d1SDavid du Colombier for(p = *l; p; p = p->rendhash) { 8203e12c5d1SDavid du Colombier if(p->rendtag == tag) { 8213e12c5d1SDavid du Colombier *l = p->rendhash; 8223e12c5d1SDavid du Colombier val = p->rendval; 8233e12c5d1SDavid du Colombier p->rendval = arg[1]; 8247dd7cddfSDavid du Colombier 825219b2ee8SDavid du Colombier while(p->mach != 0) 8263e12c5d1SDavid du Colombier ; 8273e12c5d1SDavid du Colombier ready(p); 8287dd7cddfSDavid du Colombier unlock(up->rgrp); 8293e12c5d1SDavid du Colombier return val; 8303e12c5d1SDavid du Colombier } 8313e12c5d1SDavid du Colombier l = &p->rendhash; 8323e12c5d1SDavid du Colombier } 8333e12c5d1SDavid du Colombier 8343e12c5d1SDavid du Colombier /* Going to sleep here */ 8357dd7cddfSDavid du Colombier up->rendtag = tag; 8367dd7cddfSDavid du Colombier up->rendval = arg[1]; 8377dd7cddfSDavid du Colombier up->rendhash = *l; 8387dd7cddfSDavid du Colombier *l = up; 8397dd7cddfSDavid du Colombier up->state = Rendezvous; 8407dd7cddfSDavid du Colombier unlock(up->rgrp); 8413ff48bf5SDavid du Colombier if (edf->isedf(up)) 8423ff48bf5SDavid du Colombier edf->edfblock(up); 843219b2ee8SDavid du Colombier 8443e12c5d1SDavid du Colombier sched(); 8453e12c5d1SDavid du Colombier 8467dd7cddfSDavid du Colombier return up->rendval; 8473e12c5d1SDavid du Colombier } 848