Annotation of researchv10no/sys/fs/proca.c, revision 1.1.1.1

1.1       root        1: #include "sys/param.h"
                      2: #include "sys/systm.h"
                      3: #include "sys/inode.h"
                      4: #include "sys/dir.h"
                      5: #include "sys/user.h"
                      6: #include "sys/psl.h"
                      7: #include "sys/stat.h"
                      8: #include "sys/buf.h"
                      9: #include "sys/pte.h"
                     10: #include "sys/cmap.h"
                     11: #include "sys/mtpr.h"
                     12: #include "sys/vmparam.h"
                     13: #include "sys/vmmac.h"
                     14: #include "sys/proc.h"
                     15: #include "sys/text.h"
                     16: #include "sys/file.h"
                     17: #include "sys/reg.h"
                     18: #include "sys/pioctl.h"
                     19: #include "sys/conf.h"
                     20: 
                     21: /* I/O via /proc returns EBUSY if any of these bits are set in p_flag: */
                     22: 
                     23: #define        SPRBUSY (SLOCK|SPAGE|SKEEP|SWEXIT|SPROCIO)
                     24: 
                     25: #define SYSADR ((caddr_t)0x80000000)   /* virtual address  of system seg. */
                     26: #define SYSP   btop(0x80000000)        /* virtual page no. of system seg. */
                     27: 
                     28: /* <text page no.> + P1OFF(p) == <stack page no.> of same location */
                     29: 
                     30: #define P1OFF(p)       (SYSP - (p)->p_szpt*NPTEPG)
                     31: 
                     32: #define TEXT           0
                     33: #define DATA           1
                     34: #define STACK          2
                     35: #define USERAREA       3
                     36: 
                     37: #define min(a,b)       ((a) <= (b) ? (a) : (b))
                     38: 
                     39: /* inumber to pid */
                     40: #define PRMAGIC 64
                     41: 
                     42: #define PROCDEV (dev_t)0
                     43: #define        PRROOT  2
                     44: 
                     45: struct proc *prpidlock, *prpidwant, *pritop();
                     46: 
                     47: struct pte *Prbufmap; char *priobuf;
                     48: struct pte *Prusrmap; struct user *prusrutl;
                     49: struct pte *prclmap();
                     50: 
                     51: int prput(), prread(), prwrite(), prstat();
                     52: int prmount(), prioctl(), prnami();
                     53: 
                     54: struct fstypsw prfs =
                     55: fsinit(prput, nulldev, prread, prwrite, nulldev, prstat,
                     56:        prnami, prmount, prioctl, nullopen, nodev);
                     57: 
                     58: prput(ip)
                     59: struct inode *ip;
                     60: {      struct proc *p;
                     61:        if(ip->i_number == PRROOT)
                     62:                return;
                     63:        if ((p = pritop(ip)) == NULL)
                     64:                return;
                     65:        p->p_trace = 0;
                     66: }
                     67: 
                     68: #define SDSIZ  sizeof(struct direct)
                     69: 
                     70: prread(ip)
                     71: struct inode *ip;
                     72: {
                     73:        static struct direct dotbuf[] = {
                     74:                { PRROOT, "."},
                     75:                { PRROOT, ".."}
                     76:        };
                     77:        struct direct dirbuf;
                     78:        register int i, n, j;
                     79:        int minproc, maxproc, modoff;
                     80:        struct proc *p;
                     81: 
                     82:        if (ip->i_number == PRROOT) {   /* fake up . .. and the proc inodes */
                     83:                if (Lsign(u.u_offset) < 0 || Ltol(u.u_offset) >= ip->i_size ||
                     84:                    u.u_count <= 0)
                     85:                        return;
                     86:                if (Ltol(u.u_offset) < 2*SDSIZ) {
                     87:                        iomove((caddr_t)dotbuf + Ltol(u.u_offset),
                     88:                            min(u.u_count, 2*SDSIZ - Ltol(u.u_offset)), B_READ);
                     89:                        if (u.u_count <= 0 || u.u_error)
                     90:                                return;
                     91:                }
                     92:                minproc = (Ltol(u.u_offset) - 2*SDSIZ)/SDSIZ;
                     93:                maxproc = (Ltol(u.u_offset) + u.u_count - 1)/SDSIZ;
                     94:                modoff = Ltol(u.u_offset) % SDSIZ;
                     95:                for (j = 0; j < DIRSIZ; j++)
                     96:                        dirbuf.d_name[j] = 0;
                     97:                for (i=minproc; i<min(maxproc,proccnt); i++) {
                     98:                        if (proc[i].p_stat == 0)
                     99:                                dirbuf.d_ino = 0;
                    100:                        else {
                    101:                                n = proc[i].p_pid;
                    102:                                dirbuf.d_ino = n + PRMAGIC;
                    103:                                for (j = 4; j >= 0; j--)
                    104:                                        dirbuf.d_name[j] = n%10 + '0', n /= 10;
                    105:                        }
                    106:                        iomove((caddr_t)&dirbuf + modoff,
                    107:                            min(u.u_count, SDSIZ - modoff), B_READ);
                    108:                        if (u.u_count <= 0 || u.u_error)
                    109:                                return;
                    110:                        modoff = 0;
                    111:                }
                    112:        } else if ((p = pritop(ip)) != NULL) {
                    113:                if (prlock(p))
                    114:                        return;
                    115:                prusrio(p, B_READ);
                    116:                prunlock(p);
                    117:        }
                    118: }
                    119: 
                    120: prwrite(ip)
                    121: struct inode *ip;
                    122: {
                    123:        register struct proc *p;
                    124:        if (ip->i_number == PRROOT) {
                    125:                u.u_error = EISDIR;
                    126:        } else if ((p = pritop(ip)) != NULL) {
                    127:                if (prlock(p))
                    128:                        return;
                    129:                prusrio(p, B_WRITE);
                    130:                prunlock(p);
                    131:        }
                    132: }
                    133: 
                    134: prstat(ip, ub)
                    135: struct inode *ip;
                    136: struct stat *ub;
                    137: {      struct stat ds; struct proc *p = (struct proc *)0;
                    138:        if(ip->i_number == PRROOT || (p = pritop(ip)) != NULL) {
                    139:                ds.st_dev = -1;         /* who knows */
                    140:                ds.st_ino = ip->i_number;
                    141:                ds.st_mode = ip->i_mode;
                    142:                ds.st_nlink = ip->i_nlink;
                    143:                ds.st_uid = ip->i_uid;
                    144:                ds.st_gid = ip->i_gid;
                    145:                ds.st_rdev = -1;
                    146:                if (p) ip->i_size =
                    147:                        (int)ptob(p->p_tsize+p->p_dsize+p->p_ssize+UPAGES);
                    148:                ds.st_size = ip->i_size;
                    149:                ds.st_atime = ds.st_mtime = ds.st_ctime = time;
                    150:                if(copyout((caddr_t)&ds, (caddr_t)ub, sizeof(ds)) < 0)
                    151:                        u.u_error = EFAULT;
                    152:        }
                    153: }
                    154: 
                    155: prnami(p, flagp, follow)
                    156: register struct nx *p;
                    157: struct argnamei *flagp;
                    158: {
                    159:        register struct inode *dp;
                    160:        register char *cp;
                    161:        register int n;
                    162: 
                    163:        cp = p->cp;
                    164:        dp = p->dp;
                    165:        if ((dp->i_mode & IFMT) != IFDIR) {
                    166:                u.u_error = ENOTDIR;
                    167:                goto error;
                    168:        }
                    169:        if (access(dp, IEXEC))
                    170:                goto error;
                    171:        if (flagp->flag != NI_SEARCH) {
                    172:                u.u_error = EACCES;
                    173:                goto error;
                    174:        }
                    175: rootloop:
                    176:        if (cp[0] == 0)                 /* "" == root */
                    177:                return (0);
                    178:        if (cp[0] == '.') {
                    179:                if (cp[1] == 0)         /* "." */
                    180:                        return (0);
                    181:                if (cp[1] == '/') {     /* "./" ... */
                    182:                        cp += 2;
                    183:                        p->cp = cp;
                    184:                        goto rootloop;
                    185:                }
                    186:                if (cp[1] == '.' && (cp[2] == 0 || cp[2] == '/')) {     /* ".." */
                    187:                        p->dp = dp->i_mpoint;
                    188:                        iput(dp);
                    189:                        plock(p->dp);
                    190:                        p->dp->i_count++;
                    191:                        return (1);     /* cp still points to ".." */
                    192:                }
                    193:                u.u_error = ENOENT;     /* ".somethingelse" */
                    194:                goto error;
                    195:        }
                    196:        n = 0;
                    197:        while (*cp >= '0' && *cp <= '9') {
                    198:                n *= 10;
                    199:                n += *cp++ - '0';
                    200:        }
                    201:        if (*cp) {              /* non-digit, or /proc/123/... */
                    202:                u.u_error = ENOENT;
                    203:                goto error;
                    204:        }
                    205:        p->dp = iget(dp, PROCDEV, n + PRMAGIC);
                    206:        if (p->dp == NULL)
                    207:                goto error;
                    208:        if (p->dp->i_count == 1 && prfillin(p->dp))
                    209:                goto error;
                    210:        iput(dp);
                    211:        return (0);
                    212: 
                    213: error:
                    214:        p->dp = NULL;
                    215:        iput(dp);
                    216:        return (0);
                    217: }
                    218: 
                    219: prfillin(ip)
                    220: register struct inode *ip;
                    221: {
                    222:        register struct proc *p;
                    223:        register int n;
                    224: 
                    225:        ip->i_un.i_proc = NULL;         /* safety */
                    226:        n = ip->i_number - PRMAGIC;
                    227:        for (p = proc; p < procNPROC; p++)
                    228:                if (p->p_stat && p->p_pid == n)
                    229:                        break;
                    230:        if (p == procNPROC || p->p_stat == SZOMB || p->p_trace) {
                    231:                iput(ip);
                    232:                u.u_error = ENOENT;
                    233:                return (1);
                    234:        }
                    235:        p->p_trace = ip;
                    236:        if (p->p_textp && p->p_textp->x_iptr && access(p->p_textp->x_iptr, IREAD))
                    237:                ip->i_mode = IFREG;             /* regular, no permissions */
                    238:        else
                    239:                ip->i_mode = IFREG | 0600;      /* regular, r/w only by owner */
                    240:        ip->i_nlink = 1;
                    241:        ip->i_uid = p->p_uid;
                    242:        ip->i_gid = 1;                  /* who cares */
                    243:        ip->i_size = (int)ptob(p->p_tsize+p->p_dsize+p->p_ssize+UPAGES);
                    244:        ip->i_un.i_proc = p;
                    245:        ip->i_un.i_sigmask = 0;         /* signal trace mask */
                    246:        return (0);
                    247: }
                    248: 
                    249: prmount(sip, ip, flag, mnt, fstyp)
                    250: struct inode *sip, *ip;
                    251: {
                    252:        if (!suser())
                    253:                return;
                    254:        if (mnt)
                    255:                pron(sip, ip, flag, fstyp);
                    256:        else
                    257:                proff(ip, fstyp);
                    258: }
                    259: 
                    260: pron(sip, ip, flag, fstyp)
                    261: struct inode *sip;
                    262: register struct inode *ip;
                    263: {
                    264:        register struct inode *rip;
                    265:        struct inode pi;
                    266: 
                    267:        if (ip->i_fstyp == fstyp) {
                    268:                u.u_error = EBUSY;
                    269:                return;
                    270:        }
                    271:        pi.i_fstyp = fstyp;
                    272:        pi.i_mpoint = NULL;
                    273:        if ((rip = iget(&pi, PROCDEV, (ino_t)PRROOT)) == NULL)
                    274:                return;
                    275:        if (rip->i_count != 1) {        /* already mounted */
                    276:                iput(rip);
                    277:                u.u_error = EBUSY;
                    278:                return;
                    279:        }
                    280:        rip->i_mpoint = ip;
                    281:        rip->i_mode = IFDIR|0555;
                    282:        rip->i_nlink = 2;
                    283:        rip->i_uid = rip->i_gid = 0;
                    284:        rip->i_size = (proccnt+2) * sizeof(struct direct);
                    285:        prele(rip);
                    286:        ip->i_mroot = rip;
                    287:        ip->i_count++;
                    288: }
                    289: 
                    290: proff(mip, fstyp)
                    291: struct inode *mip;
                    292: {
                    293:        struct inode *rip;
                    294: 
                    295:        plock(mip);
                    296:        rip = mip->i_mroot;
                    297:        mip->i_mroot = NULL;
                    298:        iput(mip);
                    299:        plock(rip);
                    300:        iput(rip);
                    301: }
                    302: 
                    303: /* special tracing stuff */
                    304: prioctl(ip, cmd, cmaddr)
                    305: struct inode *ip;
                    306: caddr_t cmaddr;
                    307: {
                    308:        register struct proc *p; struct text *xp; struct inode *ixp;
                    309:        int n;          /* mostly for integer arguments */
                    310: 
                    311:        if ((p = pritop(ip)) == NULL)
                    312:                return;
                    313:        switch (cmd) {
                    314:        default:
                    315:                u.u_error = ENOTTY;
                    316:                return;
                    317: 
                    318:        case PIOCGETPR:         /* read struct proc */
                    319:                if (copyout((char *)p, cmaddr, sizeof(struct proc)))
                    320:                        u.u_error = EFAULT;
                    321:                return;
                    322: 
                    323:        case PIOCOPENT:         /* open text file for reading */
                    324:                if ((xp = p->p_textp) && (ixp = xp->x_iptr)) {
                    325:                        plock(ixp);
                    326:                        ixp->i_count++;
                    327:                        open1(ixp, FREAD, 0);   /* fairly magic linkage */
                    328:                } else
                    329:                        u.u_error = ENOENT;
                    330:                return;
                    331: 
                    332:        case PIOCSTOP:          /* send STOP signal and... */
                    333:                if (p->p_stat != SSTOP)
                    334:                        psignal(p, SIGSTOP);
                    335:                                /* fall through */
                    336:        case PIOCWSTOP:         /* wait for process to STOP */
                    337:                if (p->p_stat != SSTOP)
                    338:                        tsleep((caddr_t)p->p_trace, PZERO+1, 0);
                    339:                if (p->p_pid != (ip->i_number - PRMAGIC)
                    340:                ||  p->p_stat == SZOMB)
                    341:                        u.u_error = ENOENT;
                    342:                else if (p->p_stat != SSTOP)
                    343:                        u.u_error = EINTR;
                    344:                return;
                    345: 
                    346:        case PIOCRUN:           /* make process runnable */
                    347:                if (p->p_stat == SSTOP)
                    348:                        setrun(p);
                    349:                return;
                    350: 
                    351:        case PIOCSMASK:         /* set signal trace mask */
                    352:                if (copyin(cmaddr, (caddr_t)&ip->i_un.i_sigmask, sizeof(long))) {
                    353:                        u.u_error = EFAULT;
                    354:                        return;
                    355:                }
                    356:                if (ip->i_un.i_sigmask)
                    357:                        p->p_flag |=  (STRC|SPROCTR);
                    358:                else
                    359:                        p->p_flag &= ~(STRC|SPROCTR);
                    360:                return;
                    361: 
                    362:        case PIOCCSIG:          /* clear current signal */
                    363:                p->p_cursig = 0;
                    364:                return;
                    365: 
                    366:        case PIOCSSIG:          /* set current signal */
                    367:                if (p->p_stat != SSTOP)
                    368:                        u.u_error = EBUSY;
                    369:                else if (copyin(cmaddr, (caddr_t)&n, sizeof(n)))
                    370:                        u.u_error = EFAULT;
                    371:                else if ((unsigned)n > NSIG)
                    372:                        u.u_error = EINVAL;
                    373:                else
                    374:                        p->p_cursig = n;
                    375:                return;
                    376: 
                    377:        case PIOCKILL:          /* send signal */
                    378:                if (copyin(cmaddr, (caddr_t)&n, sizeof(n)))
                    379:                        u.u_error = EFAULT;
                    380:                else if ((unsigned)n > NSIG)
                    381:                        u.u_error = EINVAL;
                    382:                else
                    383:                        psignal(p, n);
                    384:                return;
                    385: 
                    386:        case PIOCSEXEC:         /* stop on exec */
                    387:                p->p_flag |=  SSEXEC;
                    388:                return;
                    389: 
                    390:        case PIOCREXEC:         /* run on exec */
                    391:                p->p_flag &= ~SSEXEC;
                    392:                return;
                    393: 
                    394:        case PIOCNICE:          /* set nice priority */
                    395:                if (copyin(cmaddr, (caddr_t)&n, sizeof(n))) {
                    396:                        u.u_error = EFAULT;
                    397:                        return;
                    398:                }
                    399:                n += p->p_nice;
                    400:                if (n >= 2*NZERO)
                    401:                        n = 2*NZERO -1;
                    402:                if (n < 0)
                    403:                        n = 0;
                    404:                if (n < p->p_nice && !suser())
                    405:                        return;
                    406:                p->p_nice = n;
                    407:                (void) setpri(p);
                    408:                return;
                    409:        }
                    410: }
                    411: 
                    412: /* Lock the process p. */
                    413: 
                    414: prlock(p)
                    415: register struct proc *p;
                    416: {
                    417:        int s;
                    418: 
                    419:        if (p != u.u_procp) {
                    420:        waitloop:
                    421:                if (prpidlock == p) {           /* wait if p has the interlock */
                    422:                        prpidwant = u.u_procp;
                    423:                        if (tsleep((caddr_t)&prpidlock, PZERO+1, 0) == TS_SIG)
                    424:                                return (u.u_error = EINTR);
                    425:                        goto waitloop;
                    426:                }
                    427:                if (p->p_flag & SPAGE) {        /* wait if p is paging */
                    428:                        p->p_flag |= SPROCWT;
                    429:                        if (tsleep((caddr_t)&(p->p_stat), PZERO+1, 0) == TS_SIG)
                    430:                                return (u.u_error = EINTR);
                    431:                        goto waitloop;
                    432:                }
                    433: 
                    434:                s = spl6();     /* keep clock out */
                    435: 
                    436:                if (p->p_flag&SPRBUSY || (p->p_stat != SSLEEP &&
                    437:                    p->p_stat != SRUN && p->p_stat != SSTOP)) {
                    438:                        splx(s);
                    439:                        return (u.u_error = EBUSY);
                    440:                }
                    441:                if (p->p_flag&SLOAD && p->p_stat == SRUN)
                    442:                        remrq(p);       /* he's now invisible to swtch() */
                    443: 
                    444:                /* interlock; also causes swapin, inhibits swapout, setrq, remrq */
                    445: 
                    446:                p->p_flag |= SPROCIO;
                    447: 
                    448:                splx(s);        /* now do your worst, we don't care */
                    449:        }
                    450:        u.u_procp->p_flag |= SKEEP;     /* if we get swapped, could deadlock */
                    451: 
                    452:        while ((p->p_flag&SLOAD) == 0) {
                    453:                /* sched will see SPROCIO, swap him in, and signal us */
                    454:                if (tsleep((caddr_t)&p->p_addr, PZERO+1, 0) == TS_SIG) {
                    455:                        prunlock(p);
                    456:                        return (u.u_error = EINTR);
                    457:                }
                    458:        }
                    459:        while (prpidlock) {
                    460:                prpidwant = u.u_procp;
                    461:                if (tsleep((caddr_t)&prpidlock, PZERO+1, 0) == TS_SIG) {
                    462:                        prunlock(p);
                    463:                        return (u.u_error = EINTR);
                    464:                }
                    465:        }
                    466:        prpidlock = u.u_procp;
                    467:        /* now map his user area into kernel space */
                    468:        uaccess(p, Prusrmap, prusrutl);
                    469: 
                    470:        return (u.u_error = 0);
                    471: }
                    472: 
                    473: /* Undo prlock. */
                    474: 
                    475: prunlock(p)
                    476: register struct proc *p;
                    477: {
                    478:        int s;
                    479: 
                    480:        u.u_procp->p_flag &= ~SKEEP;
                    481: 
                    482:        if (p != u.u_procp) {
                    483:                s = spl6();     /* keep clock out during process state change */
                    484:                p->p_flag  &= ~SPROCIO;
                    485:                if (p->p_flag&SLOAD && p->p_stat == SRUN)
                    486:                        setrq(p);       /* visible again to swtch() */
                    487:                splx(s);
                    488:        }
                    489:        if (prpidlock == u.u_procp) {
                    490:                prpidlock = 0;
                    491:                if (prpidwant) {
                    492:                        prpidwant = 0;
                    493:                        wakeup((caddr_t)&prpidlock);
                    494:                }
                    495:        }
                    496:        return 0;
                    497: }
                    498: 
                    499: /* Read/write from/to process p. */
                    500: 
                    501: #define REGADR(i)      ((caddr_t)(regbase + i))
                    502: #define SEEKADR                ((caddr_t)Ltol(u.u_offset))
                    503: 
                    504: prusrio(p, flag)
                    505: register struct proc *p; int flag;
                    506: {
                    507:        register int *regbase;
                    508:        caddr_t maxadr; int segment, resid;
                    509: 
                    510:        u.u_error = 0;
                    511:        if ((u_long)SEEKADR >= (u_long)(maxadr = SYSADR))
                    512:                u.u_error = EIO;
                    513:        else if (SEEKADR >= (caddr_t)USRSTACK)
                    514:                segment = USERAREA;
                    515:        else if (SEEKADR >= (maxadr = (caddr_t)USRSTACK) - (int)ptob(p->p_ssize))
                    516:                segment = STACK;
                    517:        else if (SEEKADR < (maxadr = ptob(p->p_tsize)))
                    518:                segment = TEXT;
                    519:        else if (SEEKADR < (maxadr = ptob(p->p_tsize+p->p_dsize)))
                    520:                segment = DATA;
                    521:        else
                    522:                u.u_error = EIO;
                    523:        if (p->p_flag & SSYS && segment != USERAREA)    /* too conservative? */
                    524:                u.u_error = EIO;
                    525: 
                    526:        if (u.u_error) return;
                    527: 
                    528:        if ((flag & B_READ) == 0) switch(segment) {
                    529:        case TEXT:
                    530:                prxdup(p);
                    531:                break;
                    532:        case USERAREA:
                    533:                regbase = prusrutl->u_ar0;
                    534:                if (SEEKADR < REGADR(AP) ||
                    535:                    (u_long)SEEKADR >= (u_long)(maxadr = REGADR(PS+1)))
                    536:                        u.u_error = EIO;
                    537:                else if (SEEKADR >= REGADR(PC)) ;
                    538:                else if (SEEKADR < (maxadr = REGADR(FP+1))) ;
                    539:                else if (SEEKADR < REGADR(R0))
                    540:                        u.u_error = EIO;
                    541:                else if (SEEKADR < (maxadr = REGADR(R11+1))) ;
                    542:                else if (SEEKADR < REGADR(SP) || SEEKADR >= (maxadr = REGADR(SP+1)))
                    543:                        u.u_error = EIO;
                    544:                regbase = (int *)((u_long)prusrutl + (u_long)regbase - (u_long)&u);
                    545:                if ((regbase[PS]&PSL_USERSET) != PSL_USERSET ||
                    546:                    (regbase[PS]&PSL_USERCLR) != 0)
                    547:                        u.u_error = EBUSY;
                    548:                break;
                    549:        }
                    550: 
                    551:        if (u.u_error) return;
                    552: 
                    553:        resid = u.u_count;
                    554:        if ((u_long)(Ltol(u.u_offset) + u.u_count) >= (u_long)maxadr)
                    555:                u.u_count = maxadr - (caddr_t)Ltol(u.u_offset);
                    556:        resid -= u.u_count;
                    557: 
                    558:        if (segment == USERAREA) {
                    559:                iomove((caddr_t)prusrutl + ((u_long)Ltol(u.u_offset) - (u_long)&u),
                    560:                        u.u_count, flag);
                    561:                if ((flag & B_READ) == 0) {
                    562:                        regbase[PS] |=  PSL_USERSET;
                    563:                        regbase[PS] &= ~PSL_USERCLR;
                    564:                }
                    565:        } else
                    566:                priomove(p, flag);
                    567: 
                    568:        u.u_count += resid;
                    569: }
                    570: 
                    571: /* Move data between the object process and us. */
                    572: 
                    573: priomove(p, flag)
                    574:        register struct proc *p;
                    575: {
                    576:        register struct pte *pte;
                    577:        register clofset, clcount;
                    578:        int waslocked;
                    579: 
                    580:        while (u.u_count > 0 && u.u_error == 0) {
                    581:                pte = prclmap(p, (caddr_t)Ltol(u.u_offset), &waslocked);
                    582:                clofset = Ltol(u.u_offset) & CLOFSET;
                    583:                clcount = min(u.u_count, CLSIZE*NBPG - clofset);
                    584:                iomove(&priobuf[clofset], clcount, flag);
                    585:                prclunmap(pte, flag | waslocked);
                    586:        }
                    587: }
                    588: 
                    589: /* Map and lock a cluster from process into system space. */
                    590: 
                    591: struct pte *
                    592: prclmap(p, vaddr, flagp)
                    593:        register struct proc *p;
                    594:        register caddr_t vaddr;
                    595:        int *flagp;
                    596: {
                    597:        register i;
                    598:        register struct pte *pte;
                    599:        i = clbase(btop(vaddr));
                    600:        if (isassv(p, i))
                    601:                i -= P1OFF(p);
                    602:        pte = p->p_p0br + i;
                    603: 
                    604:        *flagp = 0;
                    605:        if (pte->pg_v) {
                    606:                if (cmap[pgtocm(pte->pg_pfnum)].c_lock)
                    607:                        *flagp = B_PHYS;
                    608:                else
                    609:                        mlock(pte->pg_pfnum);
                    610:        } else {
                    611:                p->p_flag |= SDLYU;
                    612:                pagein(vaddr, prusrutl);
                    613:                p->p_flag &= ~SDLYU;
                    614:                if (!pte->pg_v)
                    615:                        panic("prclmap: pte not valid after pagein");
                    616:        }
                    617:        for (i=0; i<CLSIZE; i++) {
                    618:                *(int *)(Prbufmap + i) = PG_V | PG_KW | (pte->pg_pfnum + i);
                    619:                mtpr(TBIS, &priobuf[i*NBPG]);
                    620:        }
                    621:        return pte;
                    622: }
                    623: 
                    624: /* Release a cluster, updating its pte's. */
                    625: 
                    626: prclunmap(pte, flag)
                    627:        register struct pte *pte;
                    628: {
                    629:        register i;
                    630:        if ((flag & B_PHYS) == 0)
                    631:                munlock(pte->pg_pfnum);
                    632:        if ((flag & B_READ) == 0)       /* Write to device writes memory */
                    633:                for (i=0; i<CLSIZE; i++)
                    634:                        (pte+i)->pg_m = 1;
                    635: }
                    636: 
                    637: /* Prepare the process' text segment for writing, duplicating it if necessary. */
                    638: 
                    639: prxdup(p)
                    640:        register struct proc *p;
                    641: {
                    642:        register struct text *xp, *pxp;
                    643: 
                    644:        if ((pxp = p->p_textp) == 0)
                    645:                return 0;
                    646:        if (!(pxp->x_flag&XPAGI) && pxp->x_count == 1) {
                    647:                pxp->x_flag |= XTRC|XWRIT;
                    648:                return 0;
                    649:        }
                    650:        if (pxp->x_flag&XTRC)
                    651:                panic("prxdup");
                    652: 
                    653:        for (xp = text; xp < textNTEXT && xp->x_iptr; xp++)
                    654:                /* void */ ;
                    655:        if (xp >= textNTEXT)
                    656:                return (u.u_error = ENOSPC);
                    657: 
                    658:        xp->x_flag = XLOCK|XTRC|XLOAD;
                    659:        xp->x_size = pxp->x_size;
                    660:        if (vsxalloc(xp) == NULL)
                    661:                return (u.u_error = ENOSPC);
                    662: 
                    663:        xp->x_count = 1;
                    664:        xp->x_ccount = 0;
                    665:        xp->x_rssize = 0;
                    666:        (xp->x_iptr = pxp->x_iptr)->i_count++;
                    667: 
                    668:        xlock(pxp);
                    669:        --pxp->x_count;
                    670:        pxp->x_flag &= ~XLOCK;
                    671:        xccdec(pxp, p);
                    672: 
                    673:        p->p_textp = xp;
                    674:        xlink(p);
                    675:        p->p_flag &= ~SPAGI;
                    676: 
                    677:        prxread(p, prusrutl);
                    678: 
                    679:        xp->x_flag |= XWRIT;
                    680:        xp->x_flag &= ~XLOAD;
                    681:        xunlock(xp);
                    682:        return u.u_error;
                    683: }
                    684: 
                    685: prxread(p, up)
                    686:        register struct proc *p;
                    687:        struct user *up;
                    688: {
                    689:        register struct inode *ip = p->p_textp->x_iptr;
                    690:        register count; register struct pte *pte;
                    691:        register caddr_t vaddr = 0; int waslocked;
                    692: 
                    693:        caddr_t ubase = u.u_base; unsigned int ucount = u.u_count;
                    694:        off_t uoffset = Ltol(u.u_offset);
                    695: 
                    696:        plock(ip);
                    697:        ip->i_flag |= ITEXT;
                    698: 
                    699:        count = up->u_exdata.ux_tsize;
                    700:        if (up->u_exdata.ux_mag == 0413)        /* 0413 on 4k file sys */
                    701:                u.u_offset = ltoL(BSIZE(0));
                    702:        else
                    703:                u.u_offset = ltoL(sizeof(u.u_exdata));
                    704: 
                    705:        u.u_segflg = SEGSYS;
                    706:        u.u_count = 0;
                    707:        while (count > 0 && u.u_count == 0) {
                    708:                pte = prclmap(p, vaddr, &waslocked);
                    709:                u.u_base = (caddr_t)priobuf;
                    710:                count -= u.u_count = min(count, CLSIZE*NBPG);
                    711:                vaddr += u.u_count;
                    712:                readi(ip);
                    713:                prclunmap(pte, B_WRITE | waslocked);
                    714:        }
                    715:        prele(ip);
                    716: 
                    717:        u.u_base = ubase; u.u_count = ucount;
                    718:        u.u_offset = ltoL(uoffset); u.u_segflg = SEGUDATA;
                    719: 
                    720:        return (count ? (u.u_error = EIO) : 0);
                    721: }
                    722: 
                    723: struct proc *
                    724: pritop(ip)
                    725: struct inode *ip;
                    726: {
                    727:        register struct proc *p;
                    728: 
                    729:        if ((p = ip->i_un.i_proc) == NULL
                    730:        ||  p->p_pid != ip->i_number - PRMAGIC
                    731:        ||  p->p_stat == 0 || p->p_stat == SZOMB) {
                    732:                u.u_error = ENOENT;     /* should really be ENXIO */
                    733:                return (NULL);
                    734:        }
                    735:        return (p);
                    736: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.