Annotation of lucent/sys/src/9/port/sysfile.c, revision 1.1

1.1     ! root        1: #include       "u.h"
        !             2: #include       "../port/lib.h"
        !             3: #include       "mem.h"
        !             4: #include       "dat.h"
        !             5: #include       "fns.h"
        !             6: #include       "../port/error.h"
        !             7: 
        !             8: /*
        !             9:  * The sys*() routines needn't poperror() as they return directly to syscall().
        !            10:  */
        !            11: 
        !            12: int
        !            13: newfd(Chan *c)
        !            14: {
        !            15:        Fgrp *f = u->p->fgrp;
        !            16:        int i;
        !            17: 
        !            18:        lock(f);
        !            19:        for(i=0; i<NFD; i++)
        !            20:                if(f->fd[i] == 0){
        !            21:                        if(i > f->maxfd)
        !            22:                                f->maxfd = i;
        !            23:                        f->fd[i] = c;
        !            24:                        unlock(f);
        !            25:                        return i;
        !            26:                }
        !            27:        unlock(f);
        !            28:        exhausted("file descriptors");
        !            29:        return 0;
        !            30: }
        !            31: 
        !            32: Chan*
        !            33: fdtochan(int fd, int mode, int chkmnt, int iref)
        !            34: {
        !            35:        Chan *c;
        !            36:        Fgrp *f;
        !            37: 
        !            38:        c = 0;
        !            39:        f = u->p->fgrp;
        !            40: 
        !            41:        lock(f);
        !            42:        if(fd<0 || NFD<=fd || (c = f->fd[fd])==0) {
        !            43:                unlock(f);
        !            44:                error(Ebadfd);
        !            45:        }
        !            46:        if(iref)
        !            47:                incref(c);
        !            48:        unlock(f);
        !            49: 
        !            50:        if(chkmnt && (c->flag&CMSG)) {
        !            51:                if(iref)
        !            52:                        close(c);
        !            53:                error(Ebadusefd);
        !            54:        }
        !            55: 
        !            56:        if(mode<0 || c->mode==ORDWR)
        !            57:                return c;
        !            58: 
        !            59:        if((mode&OTRUNC) && c->mode==OREAD) {
        !            60:                if(iref)
        !            61:                        close(c);
        !            62:                error(Ebadusefd);
        !            63:        }
        !            64: 
        !            65:        if((mode&~OTRUNC) != c->mode) {
        !            66:                if(iref)
        !            67:                        close(c);
        !            68:                error(Ebadusefd);
        !            69:        }
        !            70: 
        !            71:        return c;
        !            72: }
        !            73: 
        !            74: int
        !            75: openmode(ulong o)
        !            76: {
        !            77:        if(o >= (OTRUNC|OCEXEC|ORCLOSE|OEXEC))
        !            78:                error(Ebadarg);
        !            79:        o &= ~(OTRUNC|OCEXEC|ORCLOSE);
        !            80:        if(o > OEXEC)
        !            81:                error(Ebadarg);
        !            82:        if(o == OEXEC)
        !            83:                return OREAD;
        !            84:        return o;
        !            85: }
        !            86: 
        !            87: long
        !            88: syspipe(ulong *arg)
        !            89: {
        !            90:        int fd[2];
        !            91:        Chan *c[2];
        !            92:        Dev *d;
        !            93:        Fgrp *f = u->p->fgrp;
        !            94: 
        !            95:        validaddr(arg[0], 2*BY2WD, 1);
        !            96:        evenaddr(arg[0]);
        !            97:        d = &devtab[devno('|', 0)];
        !            98:        c[0] = (*d->attach)(0);
        !            99:        c[1] = 0;
        !           100:        fd[0] = -1;
        !           101:        fd[1] = -1;
        !           102:        if(waserror()){
        !           103:                close(c[0]);
        !           104:                if(c[1])
        !           105:                        close(c[1]);
        !           106:                if(fd[0] >= 0)
        !           107:                        f->fd[fd[0]]=0;
        !           108:                if(fd[1] >= 0)
        !           109:                        f->fd[fd[1]]=0;
        !           110:                nexterror();
        !           111:        }
        !           112:        c[1] = (*d->clone)(c[0], 0);
        !           113:        (*d->walk)(c[0], "data");
        !           114:        (*d->walk)(c[1], "data1");
        !           115:        c[0] = (*d->open)(c[0], ORDWR);
        !           116:        c[1] = (*d->open)(c[1], ORDWR);
        !           117:        fd[0] = newfd(c[0]);
        !           118:        fd[1] = newfd(c[1]);
        !           119:        ((long*)arg[0])[0] = fd[0];
        !           120:        ((long*)arg[0])[1] = fd[1];
        !           121:        poperror();
        !           122:        return 0;
        !           123: }
        !           124: 
        !           125: long
        !           126: sysdup(ulong *arg)
        !           127: {
        !           128:        int fd;
        !           129:        Chan *c, *oc;
        !           130:        Fgrp *f = u->p->fgrp;
        !           131: 
        !           132:        /*
        !           133:         * Close after dup'ing, so date > #d/1 works
        !           134:         */
        !           135:        c = fdtochan(arg[0], -1, 0, 1);
        !           136:        fd = arg[1];
        !           137:        if(fd != -1){
        !           138:                if(fd<0 || NFD<=fd) {
        !           139:                        close(c);
        !           140:                        error(Ebadfd);
        !           141:                }
        !           142:                lock(f);
        !           143:                if(fd > f->maxfd)
        !           144:                        f->maxfd = fd;
        !           145: 
        !           146:                oc = f->fd[fd];
        !           147:                f->fd[fd] = c;
        !           148:                unlock(f);
        !           149:                if(oc)
        !           150:                        close(oc);
        !           151:        }else{
        !           152:                if(waserror()) {
        !           153:                        close(c);
        !           154:                        nexterror();
        !           155:                }
        !           156:                fd = newfd(c);
        !           157:                poperror();
        !           158:        }
        !           159: 
        !           160:        return fd;
        !           161: }
        !           162: 
        !           163: long
        !           164: sysopen(ulong *arg)
        !           165: {
        !           166:        int fd;
        !           167:        Chan *c = 0;
        !           168: 
        !           169:        openmode(arg[1]);       /* error check only */
        !           170:        if(waserror()){
        !           171:                if(c)
        !           172:                        close(c);
        !           173:                nexterror();
        !           174:        }
        !           175:        validaddr(arg[0], 1, 0);
        !           176:        c = namec((char*)arg[0], Aopen, arg[1], 0);
        !           177:        fd = newfd(c);
        !           178:        poperror();
        !           179:        return fd;
        !           180: }
        !           181: 
        !           182: void
        !           183: fdclose(int fd, int flag)
        !           184: {
        !           185:        int i;
        !           186:        Chan *c;
        !           187:        Fgrp *f = u->p->fgrp;
        !           188: 
        !           189:        lock(f);
        !           190:        c = f->fd[fd];
        !           191:        if(c == 0){
        !           192:                /* can happen for users with shared fd tables */
        !           193:                unlock(f);
        !           194:                return;
        !           195:        }
        !           196:        if(flag){
        !           197:                if(c==0 || !(c->flag&flag)){
        !           198:                        unlock(f);
        !           199:                        return;
        !           200:                }
        !           201:        }
        !           202:        f->fd[fd] = 0;
        !           203:        if(fd == f->maxfd)
        !           204:                for(i=fd; --i>=0 && f->fd[i]==0; )
        !           205:                        f->maxfd = i;
        !           206: 
        !           207:        unlock(f);
        !           208:        close(c);
        !           209: }
        !           210: 
        !           211: long
        !           212: sysclose(ulong *arg)
        !           213: {
        !           214:        fdtochan(arg[0], -1, 0, 0);
        !           215:        fdclose(arg[0], 0);
        !           216: 
        !           217:        return 0;
        !           218: }
        !           219: 
        !           220: long
        !           221: unionread(Chan *c, void *va, long n)
        !           222: {
        !           223:        long nr;
        !           224:        Chan *nc;
        !           225:        Pgrp *pg;
        !           226: 
        !           227:        pg = u->p->pgrp;
        !           228:        rlock(&pg->ns);
        !           229: 
        !           230:        for(;;) {
        !           231:                /* Error causes component of union to be skipped */
        !           232:                if(waserror())
        !           233:                        goto next;
        !           234: 
        !           235:                nc = clone(c->mnt->to, 0);
        !           236:                poperror();
        !           237: 
        !           238:                if(c->mountid != c->mnt->mountid) {
        !           239:                        pprint("unionread: changed underfoot?\n");
        !           240:                        runlock(&pg->ns);
        !           241:                        close(nc);
        !           242:                        return 0;
        !           243:                }
        !           244: 
        !           245:                if(waserror()) {        
        !           246:                        close(nc);
        !           247:                        goto next;
        !           248:                }
        !           249: 
        !           250:                nc = (*devtab[nc->type].open)(nc, OREAD);
        !           251:                nc->offset = c->offset;
        !           252:                nr = (*devtab[nc->type].read)(nc, va, n, nc->offset);
        !           253:                /* devdirread e.g. changes it */
        !           254:                c->offset = nc->offset; 
        !           255:                poperror();
        !           256: 
        !           257:                close(nc);
        !           258:                if(nr > 0) {
        !           259:                        runlock(&pg->ns);
        !           260:                        return nr;
        !           261:                }
        !           262:                /* Advance to next element */
        !           263:        next:
        !           264:                c->mnt = c->mnt->next;
        !           265:                if(c->mnt == 0)
        !           266:                        break;
        !           267:                c->mountid = c->mnt->mountid;
        !           268:                c->offset = 0;
        !           269:        }
        !           270:        runlock(&pg->ns);
        !           271:        return 0;
        !           272: }
        !           273: 
        !           274: long
        !           275: sysread(ulong *arg)
        !           276: {
        !           277:        int dir;
        !           278:        long n;
        !           279:        Chan *c;
        !           280: 
        !           281:        validaddr(arg[1], arg[2], 1);
        !           282:        c = fdtochan(arg[0], OREAD, 1, 1);
        !           283:        if(waserror()) {
        !           284:                close(c);
        !           285:                nexterror();
        !           286:        }
        !           287: 
        !           288:        n = arg[2];
        !           289:        dir = c->qid.path&CHDIR;
        !           290: 
        !           291:        if(dir) {
        !           292:                n -= n%DIRLEN;
        !           293:                if(c->offset%DIRLEN || n==0)
        !           294:                        error(Etoosmall);
        !           295:        }
        !           296: 
        !           297:        if(dir && c->mnt)
        !           298:                n = unionread(c, (void*)arg[1], n);
        !           299:        else
        !           300:                n = (*devtab[c->type].read)(c, (void*)arg[1], n, c->offset);
        !           301: 
        !           302:        lock(c);
        !           303:        c->offset += n;
        !           304:        unlock(c);
        !           305: 
        !           306:        poperror();
        !           307:        close(c);
        !           308: 
        !           309:        return n;
        !           310: }
        !           311: 
        !           312: long
        !           313: syswrite(ulong *arg)
        !           314: {
        !           315:        Chan *c;
        !           316:        long n;
        !           317: 
        !           318:        validaddr(arg[1], arg[2], 0);
        !           319:        c = fdtochan(arg[0], OWRITE, 1, 1);
        !           320:        if(waserror()) {
        !           321:                close(c);
        !           322:                nexterror();
        !           323:        }
        !           324: 
        !           325:        if(c->qid.path & CHDIR)
        !           326:                error(Eisdir);
        !           327: 
        !           328:        n = (*devtab[c->type].write)(c, (void*)arg[1], arg[2], c->offset);
        !           329: 
        !           330:        lock(c);
        !           331:        c->offset += n;
        !           332:        unlock(c);
        !           333: 
        !           334:        poperror();
        !           335:        close(c);
        !           336: 
        !           337:        return n;
        !           338: }
        !           339: 
        !           340: long
        !           341: sysseek(ulong *arg)
        !           342: {
        !           343:        Chan *c;
        !           344:        char buf[DIRLEN];
        !           345:        Dir dir;
        !           346:        long off;
        !           347: 
        !           348:        c = fdtochan(arg[0], -1, 1, 0);
        !           349:        if(c->qid.path & CHDIR)
        !           350:                error(Eisdir);
        !           351: 
        !           352:        if(devchar[c->type] == '|')
        !           353:                error(Eisstream);
        !           354: 
        !           355:        off = 0;
        !           356:        switch(arg[2]){
        !           357:        case 0:
        !           358:                off = c->offset = arg[1];
        !           359:                break;
        !           360: 
        !           361:        case 1:
        !           362:                lock(c);        /* lock for read/write update */
        !           363:                c->offset += (long)arg[1];
        !           364:                off = c->offset;
        !           365:                unlock(c);
        !           366:                break;
        !           367: 
        !           368:        case 2:
        !           369:                (*devtab[c->type].stat)(c, buf);
        !           370:                convM2D(buf, &dir);
        !           371:                c->offset = dir.length + (long)arg[1];
        !           372:                off = c->offset;
        !           373:                break;
        !           374:        }
        !           375:        return off;
        !           376: }
        !           377: 
        !           378: long
        !           379: sysfstat(ulong *arg)
        !           380: {
        !           381:        Chan *c;
        !           382: 
        !           383:        validaddr(arg[1], DIRLEN, 1);
        !           384:        evenaddr(arg[1]);
        !           385:        c = fdtochan(arg[0], -1, 0, 1);
        !           386:        if(waserror()) {
        !           387:                close(c);
        !           388:                nexterror();
        !           389:        }
        !           390:        (*devtab[c->type].stat)(c, (char*)arg[1]);
        !           391:        poperror();
        !           392:        close(c);
        !           393:        return 0;
        !           394: }
        !           395: 
        !           396: long
        !           397: sysstat(ulong *arg)
        !           398: {
        !           399:        Chan *c;
        !           400: 
        !           401:        validaddr(arg[1], DIRLEN, 1);
        !           402:        evenaddr(arg[1]);
        !           403:        validaddr(arg[0], 1, 0);
        !           404:        c = namec((char*)arg[0], Aaccess, 0, 0);
        !           405:        if(waserror()){
        !           406:                close(c);
        !           407:                nexterror();
        !           408:        }
        !           409:        (*devtab[c->type].stat)(c, (char*)arg[1]);
        !           410:        poperror();
        !           411:        close(c);
        !           412:        return 0;
        !           413: }
        !           414: 
        !           415: long
        !           416: syschdir(ulong *arg)
        !           417: {
        !           418:        Chan *c;
        !           419: 
        !           420:        validaddr(arg[0], 1, 0);
        !           421:        c = namec((char*)arg[0], Atodir, 0, 0);
        !           422:        close(u->dot);
        !           423:        u->dot = c;
        !           424:        return 0;
        !           425: }
        !           426: 
        !           427: long
        !           428: bindmount(ulong *arg, int ismount)
        !           429: {
        !           430:        Chan *c0, *c1, *bc;
        !           431:        ulong flag;
        !           432:        long ret;
        !           433:        int fd;
        !           434:        struct{
        !           435:                Chan    *chan;
        !           436:                char    *spec;
        !           437:        }bogus;
        !           438: 
        !           439:        flag = arg[2];
        !           440:        fd = arg[0];
        !           441:        if(flag>MMASK || (flag&MORDER)==(MBEFORE|MAFTER))
        !           442:                error(Ebadarg);
        !           443:        if(ismount){
        !           444:                bc = fdtochan(fd, 2, 0, 1);
        !           445:                if(waserror()) {
        !           446:                        close(bc);
        !           447:                        nexterror();
        !           448:                }
        !           449:                bogus.chan = bc;
        !           450: 
        !           451:                validaddr(arg[3], 1, 0);
        !           452:                if(vmemchr((char*)arg[3], '\0', NAMELEN) == 0)
        !           453:                        error(Ebadarg);
        !           454: 
        !           455:                bogus.spec = (char*)arg[3];
        !           456: 
        !           457:                ret = devno('M', 0);
        !           458:                c0 = (*devtab[ret].attach)((char*)&bogus);
        !           459: 
        !           460:                poperror();
        !           461:                close(bc);
        !           462:        }
        !           463:        else {
        !           464:                validaddr(arg[0], 1, 0);
        !           465:                c0 = namec((char*)arg[0], Aaccess, 0, 0);
        !           466:        }
        !           467:        if(waserror()){
        !           468:                close(c0);
        !           469:                nexterror();
        !           470:        }
        !           471:        validaddr(arg[1], 1, 0);
        !           472:        c1 = namec((char*)arg[1], Amount, 0, 0);
        !           473:        if(waserror()){
        !           474:                close(c1);
        !           475:                nexterror();
        !           476:        }
        !           477:        if((c0->qid.path^c1->qid.path) & CHDIR)
        !           478:                error(Emount);
        !           479:        if(flag && !(c0->qid.path&CHDIR))
        !           480:                error(Emount);
        !           481:        ret = mount(c0, c1, flag);
        !           482:        poperror();
        !           483:        close(c1);
        !           484:        poperror();
        !           485:        close(c0);
        !           486:        if(ismount)
        !           487:                fdclose(fd, 0);
        !           488:        return ret;
        !           489: }
        !           490: 
        !           491: long
        !           492: sysbind(ulong *arg)
        !           493: {
        !           494:        return bindmount(arg, 0);
        !           495: }
        !           496: 
        !           497: long
        !           498: sysmount(ulong *arg)
        !           499: {
        !           500:        return bindmount(arg, 1);
        !           501: }
        !           502: 
        !           503: long
        !           504: sysunmount(ulong *arg)
        !           505: {
        !           506:        Chan *cmount, *cmounted;
        !           507: 
        !           508:        cmounted = 0;
        !           509: 
        !           510:        validaddr(arg[1], 1, 0);
        !           511:        cmount = namec((char *)arg[1], Amount, 0, 0);
        !           512: 
        !           513:        if(arg[0]) {
        !           514:                if(waserror()) {
        !           515:                        close(cmount);
        !           516:                        nexterror();
        !           517:                }
        !           518:                validaddr(arg[0], 1, 0);
        !           519:                cmounted = namec((char*)arg[0], Aopen, OREAD, 0);
        !           520:                poperror();
        !           521:        }
        !           522: 
        !           523:        if(waserror()) {
        !           524:                close(cmount);
        !           525:                if(cmounted)
        !           526:                        close(cmounted);
        !           527:                nexterror();
        !           528:        }
        !           529:        unmount(cmount, cmounted);
        !           530:        close(cmount);
        !           531:        if(cmounted)
        !           532:                close(cmounted);
        !           533:        poperror();     
        !           534:        return 0;
        !           535: }
        !           536: 
        !           537: long
        !           538: syscreate(ulong *arg)
        !           539: {
        !           540:        int fd;
        !           541:        Chan *c = 0;
        !           542: 
        !           543:        openmode(arg[1]);       /* error check only */
        !           544:        if(waserror()) {
        !           545:                if(c)
        !           546:                        close(c);
        !           547:                nexterror();
        !           548:        }
        !           549:        validaddr(arg[0], 1, 0);
        !           550:        c = namec((char*)arg[0], Acreate, arg[1], arg[2]);
        !           551:        fd = newfd(c);
        !           552:        poperror();
        !           553:        return fd;
        !           554: }
        !           555: 
        !           556: long
        !           557: sysremove(ulong *arg)
        !           558: {
        !           559:        Chan *c;
        !           560: 
        !           561:        validaddr(arg[0], 1, 0);
        !           562:        c = namec((char*)arg[0], Aaccess, 0, 0);
        !           563:        if(waserror()){
        !           564:                c->type = 0;    /* see below */
        !           565:                close(c);
        !           566:                nexterror();
        !           567:        }
        !           568:        (*devtab[c->type].remove)(c);
        !           569:        /*
        !           570:         * Remove clunks the fid, but we need to recover the Chan
        !           571:         * so fake it up.  rootclose() is known to be a nop.
        !           572:         */
        !           573:        c->type = 0;
        !           574:        poperror();
        !           575:        close(c);
        !           576:        return 0;
        !           577: }
        !           578: 
        !           579: long
        !           580: syswstat(ulong *arg)
        !           581: {
        !           582:        Chan *c;
        !           583: 
        !           584:        validaddr(arg[1], DIRLEN, 0);
        !           585:        nameok((char*)arg[1]);
        !           586:        validaddr(arg[0], 1, 0);
        !           587:        c = namec((char*)arg[0], Aaccess, 0, 0);
        !           588:        if(waserror()){
        !           589:                close(c);
        !           590:                nexterror();
        !           591:        }
        !           592:        (*devtab[c->type].wstat)(c, (char*)arg[1]);
        !           593:        poperror();
        !           594:        close(c);
        !           595:        return 0;
        !           596: }
        !           597: 
        !           598: long
        !           599: sysfwstat(ulong *arg)
        !           600: {
        !           601:        Chan *c;
        !           602: 
        !           603:        validaddr(arg[1], DIRLEN, 0);
        !           604:        nameok((char*)arg[1]);
        !           605:        c = fdtochan(arg[0], -1, 1, 1);
        !           606:        if(waserror()) {
        !           607:                close(c);
        !           608:                nexterror();
        !           609:        }
        !           610:        (*devtab[c->type].wstat)(c, (char*)arg[1]);
        !           611:        poperror();
        !           612:        close(c);
        !           613:        return 0;
        !           614: }

unix.superglobalmegacorp.com

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