Annotation of researchv10no/sys/fs/proca.c, revision 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.