Annotation of lucent/sys/src/9/port/sysfile.c, revision 1.1.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.