Annotation of researchv10no/sys/os/sys2.c, revision 1.1.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.