Annotation of researchv10no/sys/os/sys2.c, revision 1.1

1.1     ! root        1: /*     sys2.c  4.7     81/04/13        */
        !             2: 
        !             3: #include "sys/param.h"
        !             4: #include "sys/systm.h"
        !             5: #include "sys/user.h"
        !             6: #include "sys/file.h"
        !             7: #include "sys/inode.h"
        !             8: #include "sys/pte.h"
        !             9: #include "sys/vm.h"
        !            10: #include "sys/buf.h"
        !            11: #include "sys/proc.h"
        !            12: #include "sys/conf.h"
        !            13: 
        !            14: /*
        !            15:  * READ AND WRITE ARE NEAR DUPLICATES OF EACH OTHER TO SAVE
        !            16:  * AS MUCH TIME AS POSSIBLE.
        !            17:  */
        !            18: 
        !            19: /*
        !            20:  * read system call
        !            21:  */
        !            22: read()
        !            23: {
        !            24:        register struct file *fp;
        !            25:        register struct inode *ip;
        !            26:        register struct a {
        !            27:                int     fdes;
        !            28:                char    *cbuf;
        !            29:                unsigned count;
        !            30:        } *uap;
        !            31: 
        !            32:        uap = (struct a *)u.u_ap;
        !            33:        if ((int)uap->count < 0) {
        !            34:                u.u_error = EINVAL;
        !            35:                return;
        !            36:        }
        !            37:        if ((fp = getf(uap->fdes)) == NULL) {
        !            38:                u.u_error = EBADF;
        !            39:                return;
        !            40:        }
        !            41:        if((fp->f_flag&FREAD) == 0) {
        !            42:                if((fp->f_flag & FHUNGUP) == 0) /* EOF on hungup chans */
        !            43:                        u.u_error = EBADF;
        !            44:                else if (++u.u_nbadio > 64) {
        !            45:                        if (u.u_nbadio > 128)
        !            46:                                psignal(u.u_procp, SIGKILL);
        !            47:                        else
        !            48:                                psignal(u.u_procp, SIGPIPE);
        !            49:                }
        !            50:                return;
        !            51:        }
        !            52:        u.u_base = (caddr_t)uap->cbuf;
        !            53:        u.u_count = uap->count;
        !            54:        u.u_segflg = SEGUDATA;
        !            55:        if (setjmp(u.u_qsav)) {
        !            56:                if (u.u_count == uap->count)
        !            57:                        u.u_error = EINTR;
        !            58:        } else {
        !            59:                ip = fp->f_inode;
        !            60:                u.u_offset = fp->f_offset;
        !            61:                if((ip->i_mode&(IFCHR&IFBLK)) == 0 && ip->i_sptr==NULL) {
        !            62:                        plock(ip);
        !            63:                        readi(ip);
        !            64:                        prele(ip);
        !            65:                } else
        !            66:                        readi(ip);
        !            67:                fp->f_offset = Lladd(fp->f_offset, uap->count-u.u_count);
        !            68:        }
        !            69:        u.u_r.r_val1 = uap->count-u.u_count;
        !            70: }
        !            71: 
        !            72: /*
        !            73:  * write system call
        !            74:  */
        !            75: write()
        !            76: {
        !            77:        register struct file *fp;
        !            78:        register struct inode *ip;
        !            79:        register struct a {
        !            80:                int     fdes;
        !            81:                char    *cbuf;
        !            82:                unsigned count;
        !            83:        } *uap;
        !            84: 
        !            85:        uap = (struct a *)u.u_ap;
        !            86:        if ((int)uap->count < 0) {
        !            87:                u.u_error = EINVAL;
        !            88:                return;
        !            89:        }
        !            90:        if ((fp = getf(uap->fdes)) == NULL) {
        !            91:                u.u_error = EBADF;
        !            92:                return;
        !            93:        }
        !            94:        if((fp->f_flag&FWRITE) == 0) {
        !            95:                if (fp->f_flag&FHUNGUP) {
        !            96:                        u.u_error = EPIPE;
        !            97:                        psignal(u.u_procp, SIGPIPE);
        !            98:                        return;
        !            99:                }
        !           100:                u.u_error = EBADF;
        !           101:                return;
        !           102:        }
        !           103:        u.u_base = (caddr_t)uap->cbuf;
        !           104:        u.u_count = uap->count;
        !           105:        u.u_segflg = SEGUDATA;
        !           106:        if (setjmp(u.u_qsav)) {
        !           107:                if (u.u_count == uap->count)
        !           108:                        u.u_error = EINTR;
        !           109:        } else {
        !           110:                ip = fp->f_inode;
        !           111:                u.u_offset = fp->f_offset;
        !           112:                if((ip->i_mode&(IFCHR&IFBLK)) == 0 && ip->i_sptr==0) {
        !           113:                        plock(ip);
        !           114:                        writei(ip);
        !           115:                        prele(ip);
        !           116:                } else
        !           117:                        writei(ip);
        !           118:                fp->f_offset = Lladd(fp->f_offset, uap->count-u.u_count);
        !           119:        }
        !           120:        u.u_r.r_val1 = uap->count-u.u_count;
        !           121: }
        !           122: 
        !           123: /*
        !           124:  * open system call
        !           125:  */
        !           126: open()
        !           127: {
        !           128:        register struct inode *ip;
        !           129:        register struct a {
        !           130:                char    *fname;
        !           131:                int     rwmode;
        !           132:        } *uap;
        !           133: 
        !           134:        uap = (struct a *)u.u_ap;
        !           135:        ip = namei(uap->fname, SEGUDATA, &nilargnamei, 1);
        !           136:        if(ip == NULL)
        !           137:                return;
        !           138:        open1(ip, ++uap->rwmode, 0);
        !           139: }
        !           140: 
        !           141: /*
        !           142:  * creat system call
        !           143:  */
        !           144: creat()
        !           145: {
        !           146:        register struct inode *ip;
        !           147:        register struct a {
        !           148:                char    *fname;
        !           149:                int     fmode;
        !           150:        } *uap;
        !           151:        struct argnamei nmarg;
        !           152:        short mode;
        !           153: 
        !           154:        uap = (struct a *)u.u_ap;
        !           155:        nmarg = nilargnamei;
        !           156:        nmarg.flag = NI_CREAT;
        !           157:        nmarg.un.mode = mode = uap->fmode & 07777 & ~u.u_cmask;
        !           158:        ip = namei(uap->fname, SEGUDATA, &nmarg, 1);
        !           159:        if(ip == NULL) 
        !           160:                return;
        !           161:        open1(ip, FWRITE, (nmarg.un.mode == mode)? 1: 2);
        !           162: }
        !           163: 
        !           164: /*
        !           165:  * common code for open and creat.
        !           166:  * Check permissions, allocate an open file structure,
        !           167:  * and call the device open routine if any.
        !           168:  */
        !           169: open1(ip, mode, trf)
        !           170: register struct inode *ip;
        !           171: register mode;
        !           172: {
        !           173:        register struct file *fp;
        !           174:        int i;
        !           175: 
        !           176:        if(trf != 2) {
        !           177:                if(ip->i_count>1 && (ip->i_mode&ICONC))
        !           178:                        concurrency(ip, mode);
        !           179:                if(mode&FREAD)
        !           180:                        (void) access(ip, IREAD);
        !           181:                if(mode&FWRITE) {
        !           182:                        (void) access(ip, IWRITE);
        !           183:                        if((ip->i_mode&IFMT) == IFDIR)
        !           184:                                u.u_error = EISDIR;
        !           185:                }
        !           186:        }
        !           187:        if(u.u_error)
        !           188:                goto out;
        !           189:        if(trf == 1)
        !           190:                (*fstypsw[ip->i_fstyp]->t_trunc)(ip);
        !           191:        prele(ip);
        !           192:        if ((fp = falloc()) == NULL)
        !           193:                goto out;
        !           194:        fp->f_flag = mode&(FREAD|FWRITE);
        !           195:        fp->f_inode = ip;       /* dubious, but see io/fd.c */
        !           196:        i = u.u_r.r_val1;
        !           197:        if ((fp->f_inode = openi(ip, mode&(FREAD|FWRITE))) != NULL)
        !           198:                return;
        !           199:        u.u_ofile[i] = NULL;
        !           200:        fp->f_count--;
        !           201:        return;
        !           202: 
        !           203: out:
        !           204:        iput(ip);
        !           205: }
        !           206: 
        !           207: 
        !           208: /* Mkdir system call */
        !           209: mkdir()
        !           210: {
        !           211:        register struct a {
        !           212:                char *fname;
        !           213:                int fmode;
        !           214:        } *uap;
        !           215:        struct argnamei nmarg;
        !           216: 
        !           217:        uap = (struct a *)u.u_ap;
        !           218:        nmarg = nilargnamei;
        !           219:        nmarg.flag = NI_MKDIR;
        !           220:        nmarg.un.mode = (uap->fmode & 0777 & ~u.u_cmask) | IFDIR;
        !           221:        (void)namei(uap->fname, SEGUDATA, &nmarg, 0);
        !           222: }
        !           223: 
        !           224: /* Rmdir system call */
        !           225: rmdir()
        !           226: {      struct a {
        !           227:                char *fname;
        !           228:        };
        !           229:        struct argnamei nmarg;
        !           230: 
        !           231:        nmarg = nilargnamei;
        !           232:        nmarg.flag = NI_RMDIR;
        !           233:        (void) namei(((struct a *)u.u_ap)->fname, SEGUDATA, &nmarg, 0);
        !           234: }
        !           235: 
        !           236: /*
        !           237:  * Select system call.
        !           238:  */
        !           239: int    nselcoll;
        !           240: int    selwait;
        !           241: 
        !           242: select()
        !           243: {
        !           244:        register struct uap  {
        !           245:                int     nfd;
        !           246:                fd_set  *rp, *wp;
        !           247:                int     timo;
        !           248:        } *ap = (struct uap *)u.u_ap;
        !           249:        fd_set rd, wr, readable, writeable;
        !           250:        int nfds = 0;
        !           251:        time_t t = time;
        !           252:        int s, tsel, ncoll, rem;
        !           253:        unsigned len;
        !           254:        fd_set selscan();
        !           255: 
        !           256:        if (ap->nfd > NOFILE)
        !           257:                ap->nfd = NOFILE;
        !           258:        if (ap->nfd < 0) {
        !           259:                u.u_error = EBADF;
        !           260:                return;
        !           261:        }
        !           262: 
        !           263:        /* read in only as many words as we need */
        !           264:        len = ((ap->nfd+NBPW*NBBY-1)/(NBPW*NBBY))*NBPW;
        !           265:        if (ap->rp && copyin((caddr_t)ap->rp, (caddr_t)&rd, len))
        !           266:                return;
        !           267:        if (ap->wp && copyin((caddr_t)ap->wp, (caddr_t)&wr, len))
        !           268:                return;
        !           269: retry:
        !           270:        ncoll = nselcoll;
        !           271:        u.u_procp->p_flag |= SSEL;
        !           272:        if (ap->rp)
        !           273:                readable = selscan(ap->nfd, &rd, &nfds, FREAD);
        !           274:        if (ap->wp)
        !           275:                writeable = selscan(ap->nfd, &wr, &nfds, FWRITE);
        !           276:        if (u.u_error)
        !           277:                goto done;
        !           278:        if (nfds)
        !           279:                goto done;
        !           280:        rem = (ap->timo+999)/1000 - (time - t);
        !           281:        if (ap->timo == 0 || rem <= 0)
        !           282:                goto done;
        !           283:        s = spl6();
        !           284:        if ((u.u_procp->p_flag & SSEL) == 0 || nselcoll != ncoll) {
        !           285:                u.u_procp->p_flag &= ~SSEL;
        !           286:                splx(s);
        !           287:                goto retry;
        !           288:        }
        !           289:        u.u_procp->p_flag &= ~SSEL;
        !           290:        tsel = tsleep((caddr_t)&selwait, PZERO+1, rem);
        !           291:        splx(s);
        !           292:        switch (tsel) {
        !           293: 
        !           294:        case TS_OK:
        !           295:                goto retry;
        !           296: 
        !           297:        case TS_SIG:
        !           298:                u.u_error = EINTR;
        !           299:                return;
        !           300: 
        !           301:        case TS_TIME:
        !           302:                break;
        !           303:        }
        !           304: done:
        !           305:        u.u_r.r_val1 = nfds;
        !           306:        if (ap->rp)
        !           307:                (void)copyout((caddr_t)&readable, (caddr_t)ap->rp, len);
        !           308:        if (ap->wp)
        !           309:                (void)copyout((caddr_t)&writeable, (caddr_t)ap->wp, len);
        !           310: }
        !           311: 
        !           312: fd_set
        !           313: selscan(nfd, fdsp, nfdp, flag)
        !           314: int nfd;
        !           315: fd_set *fdsp;
        !           316: int *nfdp, flag;
        !           317: {
        !           318:        struct file *fp;
        !           319:        struct inode *ip;
        !           320:        unsigned int off, i, fd, able;
        !           321:        unsigned long bits;
        !           322:        fd_set  res;
        !           323: 
        !           324:        /* loop through all words of the set */
        !           325:        for (off=0; off<FDWORDS; off++) {
        !           326: 
        !           327:                /* loop once for each bit on in a word of the set */
        !           328:                res.fds_bits[off] = 0;
        !           329:                bits = fdsp->fds_bits[off];
        !           330:                while (i = ffs(bits)) {
        !           331:                        fd = off*(NBPW*NBBY)+i-1;
        !           332:                        if (fd >= nfd)
        !           333:                                return res;
        !           334:                        bits &= ~(1<<(i-1));
        !           335:                        fp = u.u_ofile[fd];
        !           336:                        if (fp == NULL) {
        !           337:                                u.u_error = EBADF;
        !           338:                                return res;
        !           339:                        }
        !           340:                        ip = fp->f_inode;
        !           341:                        able = 1;
        !           342:                        if (ip->i_sptr)
        !           343:                                able = stselect(ip->i_sptr, flag, *nfdp);
        !           344:                        if (able) {
        !           345:                                res.fds_bits[off] |= (1<<(i-1));
        !           346:                                (*nfdp)++;
        !           347:                        }
        !           348:                }
        !           349:        }
        !           350:        return res;
        !           351: }
        !           352: 
        !           353: selwakeup(p, coll)
        !           354: register struct proc *p;
        !           355: int coll;
        !           356: {
        !           357:        int s;
        !           358: 
        !           359:        if (coll) {
        !           360:                nselcoll++;
        !           361:                wakeup((caddr_t)&selwait);
        !           362:        }
        !           363:        if (p) {
        !           364:                s = spl6();
        !           365:                if (p->p_wchan == (caddr_t)&selwait)
        !           366:                        setrun(p);
        !           367:                else
        !           368:                        p->p_flag &= ~SSEL;
        !           369:                splx(s);
        !           370:        }
        !           371: }
        !           372: 
        !           373: /*
        !           374:  * close system call
        !           375:  */
        !           376: close()
        !           377: {
        !           378:        register struct file *fp;
        !           379:        register struct a {
        !           380:                int     fdes;
        !           381:        } *uap;
        !           382: 
        !           383:        uap = (struct a *)u.u_ap;
        !           384:        fp = getf(uap->fdes);
        !           385:        if(fp == NULL) {
        !           386:                u.u_error = EBADF;
        !           387:                return;
        !           388:        }
        !           389:        u.u_ofile[uap->fdes] = NULL;
        !           390:        closef(fp);
        !           391: }
        !           392: 
        !           393: /*
        !           394:  * [l]seek system calls
        !           395:  */
        !           396: 
        !           397: lseek()
        !           398: {
        !           399:        doseek(1);
        !           400: }
        !           401: 
        !           402: seek()
        !           403: {
        !           404:        doseek(0);
        !           405: }
        !           406: 
        !           407: doseek(islong)
        !           408: {
        !           409:        register struct file *fp;
        !           410:        register struct a {
        !           411:                int     fdes;
        !           412:                off_t   off;
        !           413:                int     sbase;
        !           414:        } *uap1;
        !           415:        register struct b {
        !           416:                int     fdes;
        !           417:                llong_t off;
        !           418:                int     sbase;
        !           419:        } *uap2;
        !           420:        llong_t off;
        !           421:        int fdes, sbase;
        !           422: 
        !           423:        if (islong) {
        !           424:                uap2 = (struct b *)u.u_ap;
        !           425:                fdes = uap2->fdes;
        !           426:                off = uap2->off;
        !           427:                sbase = uap2->sbase;
        !           428:        } else {
        !           429:                uap1 = (struct a *)u.u_ap;
        !           430:                fdes = uap1->fdes;
        !           431:                sbase = uap1->sbase;
        !           432:                off = ltoL(uap1->off);
        !           433:                if (sbase!=0) {         /* signed offset when not w.r.t. base */
        !           434:                        if (uap1->off<0)
        !           435:                                off.hi = -1;
        !           436:                }
        !           437:        }
        !           438:        fp = getf(fdes);
        !           439:        if(fp == NULL) {
        !           440:                u.u_error = EBADF;
        !           441:                return;
        !           442:        }
        !           443:        if(fp->f_inode->i_sptr) {
        !           444:                u.u_error = ESPIPE;
        !           445:                return;
        !           446:        }
        !           447:        if(sbase == 1)
        !           448:                off = LLadd(fp->f_offset, off);
        !           449:        else if(sbase == 2)
        !           450:                off = Lladd(off, fp->f_inode->i_size);
        !           451:        fp->f_offset = off;
        !           452:        u.u_r.r_val1 = Ltol(off);
        !           453:        u.u_r.r_val2 = off.hi;
        !           454: }
        !           455: 
        !           456: 
        !           457: /*
        !           458:  * link system call
        !           459:  */
        !           460: link()
        !           461: {
        !           462:        register struct inode *ip;
        !           463:        register struct a {
        !           464:                char    *target;
        !           465:                char    *linkname;
        !           466:        } *uap;
        !           467:        struct argnamei nmarg;
        !           468: 
        !           469:        uap = (struct a *)u.u_ap;
        !           470:        ip = namei(uap->target, SEGUDATA, &nilargnamei, 0);   /* well, this routine is doomed anyhow */
        !           471:        if(ip == NULL)
        !           472:                return;
        !           473:        if((ip->i_mode&IFMT)==IFDIR && !suser())
        !           474:                goto out1;
        !           475:        ip->i_nlink++;
        !           476:        ip->i_flag |= ICHG;
        !           477:        iupdat(ip, &time, &time, 1);
        !           478:        prele(ip);
        !           479:        nmarg = nilargnamei;
        !           480:        nmarg.flag = NI_LINK;
        !           481:        nmarg.un.il = ip;
        !           482:        (void) namei(uap->linkname, SEGUDATA, &nmarg, 0);
        !           483:        if(u.u_error) {
        !           484:                ip->i_nlink--;
        !           485:                ip->i_flag |= ICHG;
        !           486:        }
        !           487: out1:
        !           488:        iput(ip);
        !           489: }
        !           490: 
        !           491: /*
        !           492:  * mknod system call
        !           493:  */
        !           494: mknod()
        !           495: {
        !           496:        register struct inode *ip;
        !           497:        register struct a {
        !           498:                char    *fname;
        !           499:                int     fmode;
        !           500:                int     dev;
        !           501:        } *uap;
        !           502:        struct argnamei nmarg;
        !           503: 
        !           504:        uap = (struct a *)u.u_ap;
        !           505:        if(suser()) {
        !           506:                nmarg = nilargnamei;
        !           507:                nmarg.flag = NI_NXCREAT;
        !           508:                nmarg.un.mode = uap->fmode & ~u.u_cmask;
        !           509:                ip = namei(uap->fname, SEGUDATA, &nmarg, 0);
        !           510:        }
        !           511:        if(u.u_error)
        !           512:                return;
        !           513:        if (uap->dev) {
        !           514:                /*
        !           515:                 * Want to be able to use this to make badblock
        !           516:                 * inodes, so don't truncate the dev number.
        !           517:                 */
        !           518:                ip->i_un.i_rdev = uap->dev;
        !           519:                ip->i_flag |= IACC|IUPD|ICHG;
        !           520:        }
        !           521:        iput(ip);
        !           522: }
        !           523: 
        !           524: /*
        !           525:  * access system call
        !           526:  */
        !           527: saccess()
        !           528: {
        !           529:        register svuid, svgid;
        !           530:        register struct inode *ip;
        !           531:        register struct a {
        !           532:                char    *fname;
        !           533:                int     fmode;
        !           534:        } *uap;
        !           535: 
        !           536:        uap = (struct a *)u.u_ap;
        !           537:        svuid = u.u_uid;
        !           538:        svgid = u.u_gid;
        !           539:        u.u_uid = u.u_ruid;
        !           540:        u.u_gid = u.u_rgid;
        !           541:        ip = namei(uap->fname, SEGUDATA, &nilargnamei, 1);
        !           542:        if (ip != NULL) {
        !           543:                if (uap->fmode&(IREAD>>6))
        !           544:                        (void) access(ip, IREAD);
        !           545:                if (uap->fmode&(IWRITE>>6))
        !           546:                        (void) access(ip, IWRITE);
        !           547:                if (uap->fmode&(IEXEC>>6))
        !           548:                        (void) access(ip, IEXEC);
        !           549:                iput(ip);
        !           550:        }
        !           551:        u.u_uid = svuid;
        !           552:        u.u_gid = svgid;
        !           553: }

unix.superglobalmegacorp.com

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