diff options
Diffstat (limited to 'emu')
55 files changed, 465 insertions, 253 deletions
diff --git a/emu/FreeBSD/emu b/emu/FreeBSD/emu index 257df186..eca577a9 100644 --- a/emu/FreeBSD/emu +++ b/emu/FreeBSD/emu @@ -56,6 +56,8 @@ port cache chan dev + devtab + dial dis discall diff --git a/emu/Hp/devaudio.c b/emu/Hp/devaudio.c index c26143e3..50e17377 100644 --- a/emu/Hp/devaudio.c +++ b/emu/Hp/devaudio.c @@ -489,7 +489,9 @@ Dev audiodevtab = { 'A', "audio", + devreset, audioinit, + devshutdown, audioattach, devclone, audiowalk, @@ -57,6 +57,8 @@ port cache chan dev + devtab + dial dis discall diff --git a/emu/Irix/emu b/emu/Irix/emu index e5d92554..7dccb55c 100644 --- a/emu/Irix/emu +++ b/emu/Irix/emu @@ -56,6 +56,8 @@ port cache chan dev + devtab + dial dis discall diff --git a/emu/Linux/emu b/emu/Linux/emu index 0e7c17f9..e854a12d 100644 --- a/emu/Linux/emu +++ b/emu/Linux/emu @@ -56,6 +56,8 @@ port cache chan dev + devtab + dial dis discall diff --git a/emu/Linux/emu-g b/emu/Linux/emu-g index 31d29125..6f10f619 100644 --- a/emu/Linux/emu-g +++ b/emu/Linux/emu-g @@ -42,6 +42,8 @@ port cache chan dev + devtab + dial dis discall diff --git a/emu/MacOSX/emu b/emu/MacOSX/emu index 91efe264..c69dc633 100644 --- a/emu/MacOSX/emu +++ b/emu/MacOSX/emu @@ -56,6 +56,8 @@ port cache chan dev + devtab + dial dis discall diff --git a/emu/MacOSX/emu-g b/emu/MacOSX/emu-g index 380ece95..1f24b346 100644 --- a/emu/MacOSX/emu-g +++ b/emu/MacOSX/emu-g @@ -42,6 +42,8 @@ port cache chan dev + devtab + dial dis discall diff --git a/emu/NetBSD/emu b/emu/NetBSD/emu index 257df186..eca577a9 100644 --- a/emu/NetBSD/emu +++ b/emu/NetBSD/emu @@ -56,6 +56,8 @@ port cache chan dev + devtab + dial dis discall diff --git a/emu/Nt/devarch.c b/emu/Nt/devarch.c index 2ddaf763..4b5a9f0a 100644 --- a/emu/Nt/devarch.c +++ b/emu/Nt/devarch.c @@ -320,7 +320,9 @@ Dev archdevtab = { 'a', "arch", + devreset, archinit, + devshutdown, archattach, archwalk, archstat, diff --git a/emu/Nt/deveia.c b/emu/Nt/deveia.c index 0ffa2e7a..8b4af3bf 100644 --- a/emu/Nt/deveia.c +++ b/emu/Nt/deveia.c @@ -379,7 +379,9 @@ Dev eiadevtab = { Devchar, "eia", + devreset, eiainit, + devshutdown, eiaattach, eiawalk, eiastat, diff --git a/emu/Nt/devfs.c b/emu/Nt/devfs.c index 89d52e83..a1250d27 100644 --- a/emu/Nt/devfs.c +++ b/emu/Nt/devfs.c @@ -453,7 +453,6 @@ fswalk(Chan *c, Chan *nc, char **name, int nname) } if(nc == nil){ nc = devclone(c); - nc->type = 0; alloc = 1; } wq->clone = nc; @@ -528,7 +527,8 @@ fswalk(Chan *c, Chan *nc, char **name, int nname) wq->clone = nil; }else if(wq->clone){ nc->aux = smalloc(sizeof(Fsinfo)); - nc->type = c->type; + devtabincref(c->dev); + nc->dev = c->dev; FS(nc)->spec = FS(c)->spec; FS(nc)->srv = FS(c)->srv; FS(nc)->name = current; @@ -57,6 +57,8 @@ port cache chan dev + devtab + dial dis discall diff --git a/emu/OpenBSD/emu b/emu/OpenBSD/emu index 5130db7c..b9886176 100644 --- a/emu/OpenBSD/emu +++ b/emu/OpenBSD/emu @@ -56,6 +56,8 @@ port cache chan dev + devtab + dial dis discall diff --git a/emu/Plan9/devfs.c b/emu/Plan9/devfs.c index d0db522d..c64c0f88 100644 --- a/emu/Plan9/devfs.c +++ b/emu/Plan9/devfs.c @@ -68,7 +68,7 @@ fsattach(char *spec) c = devattach('U', spec); lock(&l); - c->dev = devno++; + c->devno = devno++; c->qid = rootqid; unlock(&l); c->aux = smalloc(sizeof(Fsinfo)); @@ -105,7 +105,6 @@ fswalk(Chan *c, Chan *nc, char **name, int nname) } if(nc == nil){ nc = devclone(c); - nc->type = 0; alloc = 1; } wq->clone = nc; @@ -152,7 +151,8 @@ fswalk(Chan *c, Chan *nc, char **name, int nname) }else if(wq->clone){ /* now attach to our device */ nc->aux = smalloc(sizeof(Fsinfo)); - nc->type = c->type; + devtabincref(c->dev); + wq->clone->dev = c->dev; FS(nc)->rootqid = FS(c)->rootqid; FS(nc)->name = current; FS(nc)->fd = -1; @@ -349,7 +349,9 @@ Dev fsdevtab = { 'U', "fs", + devreset, devinit, + devshutdown, fsattach, fswalk, fsstat, diff --git a/emu/Plan9/devsrv9.c b/emu/Plan9/devsrv9.c index 7ea26dfb..c0e0e6e8 100644 --- a/emu/Plan9/devsrv9.c +++ b/emu/Plan9/devsrv9.c @@ -128,7 +128,7 @@ srv9walk(Chan *c, Chan *nc, char **name, int nname) } if(nc == nil){ nc = devclone(c); - nc->type = 0; /* device doesn't know about this channel yet */ + /* device doesn't know about this channel yet */ alloc = 1; } wq->clone = nc; @@ -161,7 +161,8 @@ srv9walk(Chan *c, Chan *nc, char **name, int nname) wq->clone = nil; }else{ /* attach cloned channel to device */ - wq->clone->type = c->type; + devtabincref(c->dev); + wq->clone->dev = c->dev; if(wq->clone != c) nc->aux = srvget(nc->qid.path); } @@ -379,7 +380,9 @@ Dev srv9devtab = { L'₪', "srv9", + devreset, srv9init, + devshutdown, srv9attach, srv9walk, srv9stat, diff --git a/emu/Plan9/emu b/emu/Plan9/emu index 0a6c0f53..29da3d40 100644 --- a/emu/Plan9/emu +++ b/emu/Plan9/emu @@ -13,7 +13,7 @@ dev fs cmd cmd indir - sign +# sign draw win pointer @@ -33,7 +33,6 @@ lib memlayer memdraw - keyring sec mp dynld @@ -57,6 +56,8 @@ port cache chan dev + devtab + dial dis discall diff --git a/emu/Plan9/emusig b/emu/Plan9/emusig index 1975a4cc..295fb7f3 100644 --- a/emu/Plan9/emusig +++ b/emu/Plan9/emusig @@ -47,6 +47,8 @@ port cache chan dev + devtab + dial dis discall diff --git a/emu/Solaris/emu b/emu/Solaris/emu index a72e6b7b..2d83a1fc 100644 --- a/emu/Solaris/emu +++ b/emu/Solaris/emu @@ -56,6 +56,8 @@ port cache chan dev + devtab + dial dis discall diff --git a/emu/Unixware/emu b/emu/Unixware/emu index fd657978..cfb5ea80 100644 --- a/emu/Unixware/emu +++ b/emu/Unixware/emu @@ -56,6 +56,8 @@ port cache chan dev + devtab + dial dis discall diff --git a/emu/port/chan.c b/emu/port/chan.c index fc936b0f..b299db7f 100644 --- a/emu/port/chan.c +++ b/emu/port/chan.c @@ -140,15 +140,12 @@ static char isfrog[256]= void chandevinit(void) { - int i; - /* isfrog[' '] = 1; */ /* let's see what happens */ isfrog['/'] = 1; isfrog[0x7f] = 1; - for(i=0; devtab[i] != nil; i++) - devtab[i]->init(); + devtabinit(); } Chan* @@ -173,12 +170,10 @@ newchan(void) unlock(&chanalloc.l); } - /* if you get an error before associating with a dev, - close calls rootclose, a nop */ - c->type = 0; + c->dev = nil; c->flag = 0; c->r.ref = 1; - c->dev = 0; + c->devno = 0; c->offset = 0; c->iounit = 0; c->umh = 0; @@ -191,7 +186,7 @@ newchan(void) c->mqid.path = 0; c->mqid.vers = 0; c->mqid.type = 0; - c->name = 0; + c->name = nil; return c; } @@ -282,8 +277,13 @@ chanfree(Chan *c) cclose(c->mchan); c->mchan = nil; } + if(c->dev != nil){ + devtabput(c->dev); + c->dev = nil; + } cnameclose(c->name); + c->name = nil; lock(&chanalloc.l); c->next = chanalloc.free; @@ -304,7 +304,8 @@ cclose(Chan *c) return; if(!waserror()){ - devtab[c->type]->close(c); + if(c->dev != nil) + c->dev->close(c); poperror(); } @@ -341,23 +342,23 @@ eqchan(Chan *a, Chan *b, int pathonly) return 0; if(!pathonly && a->qid.vers!=b->qid.vers) return 0; - if(a->type != b->type) + if(a->dev->dc != b->dev->dc) return 0; - if(a->dev != b->dev) + if(a->devno != b->devno) return 0; return 1; } int -eqchantdqid(Chan *a, int type, int dev, Qid qid, int pathonly) +eqchanddq(Chan *a, int dc, uint devno, Qid qid, int pathonly) { if(a->qid.path != qid.path) return 0; if(!pathonly && a->qid.vers!=qid.vers) return 0; - if(a->type != type) + if(a->dev->dc != dc) return 0; - if(a->dev != dev) + if(a->devno != devno) return 0; return 1; } @@ -576,7 +577,7 @@ cclone(Chan *c) Chan *nc; Walkqid *wq; - wq = devtab[c->type]->walk(c, nil, nil, 0); + wq = c->dev->walk(c, nil, nil, 0); if(wq == nil) error("clone failed"); nc = wq->clone; @@ -588,7 +589,7 @@ cclone(Chan *c) } int -findmount(Chan **cp, Mhead **mp, int type, int dev, Qid qid) +findmount(Chan **cp, Mhead **mp, int dc, uint devno, Qid qid) { Pgrp *pg; Mhead *m; @@ -602,7 +603,7 @@ if(m->from == nil){ runlock(&m->lock); continue; } - if(eqchantdqid(m->from, type, dev, qid, 1)) { + if(eqchanddq(m->from, dc, devno, qid, 1)) { runlock(&pg->ns); if(mp != nil){ incref(&m->r); @@ -627,7 +628,7 @@ if(m->from == nil){ int domount(Chan **cp, Mhead **mp) { - return findmount(cp, mp, (*cp)->type, (*cp)->dev, (*cp)->qid); + return findmount(cp, mp, (*cp)->dev->dc, (*cp)->devno, (*cp)->qid); } Chan* @@ -682,7 +683,7 @@ static char Edoesnotexist[] = "does not exist"; int walk(Chan **cp, char **names, int nnames, int nomount, int *nerror) { - int dev, dotdot, i, n, nhave, ntry, type; + int dc, devno, dotdot, i, n, nhave, ntry; Chan *c, *nc; Cname *cname; Mount *f; @@ -734,10 +735,10 @@ walk(Chan **cp, char **names, int nnames, int nomount, int *nerror) if(!dotdot && !nomount) domount(&c, &mh); - type = c->type; - dev = c->dev; + dc = c->dev->dc; + devno = c->devno; - if((wq = devtab[type]->walk(c, nil, names+nhave, ntry)) == nil){ + if((wq = c->dev->walk(c, nil, names+nhave, ntry)) == nil){ /* try a union mount, if any */ if(mh && !nomount){ /* @@ -745,12 +746,12 @@ walk(Chan **cp, char **names, int nnames, int nomount, int *nerror) */ rlock(&mh->lock); for(f = mh->mount->next; f; f = f->next) - if((wq = devtab[f->to->type]->walk(f->to, nil, names+nhave, ntry)) != nil) + if((wq = f->to->dev->walk(f->to, nil, names+nhave, ntry)) != nil) break; runlock(&mh->lock); if(f != nil){ - type = f->to->type; - dev = f->to->dev; + dc = f->to->dev->dc; + devno = f->to->devno; } } if(wq == nil){ @@ -776,7 +777,7 @@ walk(Chan **cp, char **names, int nnames, int nomount, int *nerror) nc = nil; if(!nomount) for(i=0; i<wq->nqid && i<ntry-1; i++) - if(findmount(&nc, &nmh, type, dev, wq->qid[i])) + if(findmount(&nc, &nmh, dc, devno, wq->qid[i])) break; if(nc == nil){ /* no mount points along path */ if(wq->clone == nil){ @@ -983,7 +984,7 @@ saveregisters(void) Chan* namec(char *aname, int amode, int omode, ulong perm) { - int n, prefix, len, t, nomount, npath; + int n, prefix, len, nomount, npath; Chan *c, *cnew; Cname *cname; Elemlist e; @@ -991,6 +992,7 @@ namec(char *aname, int amode, int omode, ulong perm) Mhead *m; char *createerr, tmperrbuf[ERRMAX]; char *name; + Dev *dev; name = aname; if(name[0] == '\0') @@ -1033,10 +1035,16 @@ namec(char *aname, int amode, int omode, ulong perm) if(up->env->pgrp->nodevs && (utfrune("|esDa", r) == nil || r == 's' && up->genbuf[n]!='\0')) error(Enoattach); - t = devno(r, 1); - if(t == -1) + dev = devtabget(r, 1); + if(dev == nil) error(Ebadsharp); - c = devtab[t]->attach(up->genbuf+n); + if(waserror()){ + devtabput(dev); + nexterror(); + } + c = dev->attach(up->genbuf+n); + poperror(); + devtabput(dev); break; default: @@ -1165,7 +1173,7 @@ if(c->umh != nil){ if(omode == OEXEC) c->flag &= ~CCACHE; - c = devtab[c->type]->open(c, omode&~OCEXEC); + c = c->dev->open(c, omode&~OCEXEC); if(omode & OCEXEC) c->flag |= CCEXEC; @@ -1249,7 +1257,7 @@ if(c->umh != nil){ m = nil; cnew = nil; /* is this assignment necessary? */ if(!waserror()){ /* try create */ - if(!nomount && findmount(&cnew, &m, c->type, c->dev, c->qid)) + if(!nomount && findmount(&cnew, &m, c->dev->dc, c->devno, c->qid)) cnew = createdir(cnew, m); else{ cnew = c; @@ -1267,7 +1275,7 @@ if(c->umh != nil){ cnew->name = c->name; incref(&cnew->name->r); - devtab[cnew->type]->create(cnew, e.elems[e.nelems-1], omode&~(OEXCL|OCEXEC), perm); + cnew->dev->create(cnew, e.elems[e.nelems-1], omode&~(OEXCL|OCEXEC), perm); poperror(); if(omode & OCEXEC) cnew->flag |= CCEXEC; diff --git a/emu/port/dat.h b/emu/port/dat.h index b245b61c..90df4b87 100644 --- a/emu/port/dat.h +++ b/emu/port/dat.h @@ -108,8 +108,8 @@ struct Chan Chan* next; /* allocation */ Chan* link; vlong offset; /* in file */ - ushort type; - ulong dev; + Dev* dev; + uint devno; ushort mode; /* read/write */ ushort flag; Qid qid; @@ -142,7 +142,9 @@ struct Dev int dc; char* name; + void (*reset)(void); void (*init)(void); + void (*shutdown)(void); Chan* (*attach)(char*); Walkqid* (*walk)(Chan*, Chan*, char**, int); int (*stat)(Chan*, uchar*, int); @@ -150,18 +152,16 @@ struct Dev void (*create)(Chan*, char*, int, ulong); void (*close)(Chan*); long (*read)(Chan*, void*, long, vlong); - Block* (*bread)(Chan*, long, ulong); + Block* (*bread)(Chan*, long, vlong); long (*write)(Chan*, void*, long, vlong); - long (*bwrite)(Chan*, Block*, ulong); + long (*bwrite)(Chan*, Block*, vlong); void (*remove)(Chan*); int (*wstat)(Chan*, uchar*, int); }; enum { - BINTR = (1<<0), - BFREE = (1<<1), - BMORE = (1<<2) /* continued in next block */ + BINTR = (1<<0) }; struct Block @@ -333,8 +333,8 @@ struct Skeyset struct Uqid { Ref r; - int type; - int dev; + int dc; + int devno; vlong oldpath; vlong newpath; Uqid* next; diff --git a/emu/port/dev.c b/emu/port/dev.c index ee4053aa..2a76ec12 100644 --- a/emu/port/dev.c +++ b/emu/port/dev.c @@ -12,21 +12,6 @@ mkqid(Qid *q, vlong path, ulong vers, int type) q->path = path; } -int -devno(int c, int user) -{ - int i; - - for(i = 0; devtab[i] != nil; i++) { - if(devtab[i]->dc == c) - return i; - } - if(user == 0) - panic("devno %C 0x%ux", c, c); - - return -1; -} - void devdir(Chan *c, Qid qid, char *n, long length, char *user, long perm, Dir *db) { @@ -34,8 +19,11 @@ devdir(Chan *c, Qid qid, char *n, long length, char *user, long perm, Dir *db) if(c->flag&CMSG) qid.type |= QTMOUNT; db->qid = qid; - db->type = devtab[c->type]->dc; - db->dev = c->dev; + if(c->dev != nil) + db->type = c->dev->dc; + else + db->type = -1; + db->dev = c->devno; db->mode = perm | (qid.type << 24); db->atime = time(0); db->mtime = kerndate; @@ -66,6 +54,11 @@ devgen(Chan *c, char *name, Dirtab *tab, int ntab, int i, Dir *dp) } void +devreset(void) +{ +} + +void devinit(void) { } @@ -76,18 +69,18 @@ devshutdown(void) } Chan* -devattach(int tc, char *spec) +devattach(int dc, char *spec) { Chan *c; char *buf; c = newchan(); mkqid(&c->qid, 0, 0, QTDIR); - c->type = devno(tc, 0); + c->dev = devtabget(dc, 0); if(spec == nil) spec = ""; buf = smalloc(4+strlen(spec)+1); - sprint(buf, "#%C%s", tc, spec); + sprint(buf, "#%C%s", dc, spec); c->name = newcname(buf); free(buf); return c; @@ -99,11 +92,11 @@ devclone(Chan *c) Chan *nc; if(c->flag & COPEN) - panic("clone of open file type %C\n", devtab[c->type]->dc); + panic("clone of open file type %C\n", c->dev != nil? c->dev->dc: -1); nc = newchan(); - nc->type = c->type; - nc->dev = c->dev; + /* the caller fills in nc->dev, if and when necessary */ + nc->devno = c->devno; nc->mode = c->mode; nc->qid = c->qid; nc->offset = c->offset; @@ -137,7 +130,7 @@ devwalk(Chan *c, Chan *nc, char **name, int nname, Dirtab *tab, int ntab, Devgen } if(nc == nil){ nc = devclone(c); - nc->type = 0; /* device doesn't know about this channel yet */ + /* nc->dev remains nil for now */ alloc = 1; } wq->clone = nc; @@ -155,7 +148,15 @@ devwalk(Chan *c, Chan *nc, char **name, int nname, Dirtab *tab, int ntab, Devgen continue; } if(strcmp(n, "..") == 0){ - (*gen)(nc, nil, tab, ntab, DEVDOTDOT, &dir); + /* + * Use c->dev->name in the error because + * nc->dev should be nil here. + */ + if((*gen)(nc, nil, tab, ntab, DEVDOTDOT, &dir) != 1){ + print("devgen walk .. in dev%s %#llux broken\n", + c->dev->name, nc->qid.path); + error("broken devgen"); + } nc->qid = dir.qid; goto Accept; } @@ -201,7 +202,10 @@ Done: wq->clone = nil; }else if(wq->clone){ /* attach cloned channel to same device */ - wq->clone->type = c->type; + if(c->dev != nil){ + devtabincref(c->dev); + } + wq->clone->dev = c->dev; } return wq; } @@ -233,7 +237,7 @@ devstat(Chan *c, uchar *db, int n, Dirtab *tab, int ntab, Devgen *gen) } print("%s %s: devstat %C %llux\n", up->text, up->env->user, - devtab[c->type]->dc, c->qid.path); + c->dev->dc, c->qid.path); error(Enonexist); case 0: @@ -336,7 +340,7 @@ Return: } Block* -devbread(Chan *c, long n, ulong offset) +devbread(Chan *c, long n, vlong offset) { Block *bp; @@ -345,13 +349,13 @@ devbread(Chan *c, long n, ulong offset) freeb(bp); nexterror(); } - bp->wp += devtab[c->type]->read(c, bp->wp, n, offset); + bp->wp += c->dev->read(c, bp->wp, n, offset); poperror(); return bp; } long -devbwrite(Chan *c, Block *bp, ulong offset) +devbwrite(Chan *c, Block *bp, vlong offset) { long n; @@ -359,7 +363,7 @@ devbwrite(Chan *c, Block *bp, ulong offset) freeb(bp); nexterror(); } - n = devtab[c->type]->write(c, bp->rp, BLEN(bp), offset); + n = c->dev->write(c, bp->rp, BLEN(bp), offset); poperror(); freeb(bp); @@ -433,14 +437,3 @@ validwstatname(char *name) if(strcmp(name, ".") == 0 || strcmp(name, "..") == 0) error(Efilename); } - -Dev* -devbyname(char *name) -{ - int i; - - for(i = 0; devtab[i] != nil; i++) - if(strcmp(devtab[i]->name, name) == 0) - return devtab[i]; - return nil; -} diff --git a/emu/port/devcap.c b/emu/port/devcap.c index 00d1c2be..be1bcbeb 100644 --- a/emu/port/devcap.c +++ b/emu/port/devcap.c @@ -227,7 +227,9 @@ Dev capdevtab = { 0x00A4, /* L'¤' */ "cap", + devreset, devinit, + devshutdown, capattach, capwalk, capstat, diff --git a/emu/port/devcmd.c b/emu/port/devcmd.c index f6cccf39..49049fec 100644 --- a/emu/port/devcmd.c +++ b/emu/port/devcmd.c @@ -667,7 +667,9 @@ Dev cmddevtab = { 'C', "cmd", + devreset, cmdinit, + devshutdown, cmdattach, cmdwalk, cmdstat, diff --git a/emu/port/devcons.c b/emu/port/devcons.c index 8e823839..00fbd4d8 100644 --- a/emu/port/devcons.c +++ b/emu/port/devcons.c @@ -333,20 +333,7 @@ consread(Chan *c, void *va, long n, vlong offset) return readstr(offset, va, n, buf); case Qdrivers: - p = malloc(READSTR); - if(p == nil) - error(Enomem); - l = 0; - for(i = 0; devtab[i] != nil; i++) - l += snprint(p+l, READSTR-l, "#%C %s\n", devtab[i]->dc, devtab[i]->name); - if(waserror()){ - free(p); - nexterror(); - } - n = readstr(offset, va, n, p); - poperror(); - free(p); - return n; + return devtabread(c, buf, n, off); case Qmemory: return poolread(va, n, offset); @@ -611,7 +598,9 @@ Dev consdevtab = { 'c', "cons", + devreset, consinit, + devshutdown, consattach, conswalk, consstat, diff --git a/emu/port/devdraw.c b/emu/port/devdraw.c index bc6d6352..f4b37a44 100644 --- a/emu/port/devdraw.c +++ b/emu/port/devdraw.c @@ -2000,7 +2000,9 @@ Dev drawdevtab = { 'i', "draw", + devreset, devinit, + devshutdown, drawattach, drawwalk, drawstat, diff --git a/emu/port/devdup.c b/emu/port/devdup.c index 7796a8f9..7c4dce3c 100644 --- a/emu/port/devdup.c +++ b/emu/port/devdup.c @@ -134,7 +134,9 @@ Dev dupdevtab = { 'd', "dup", + devreset, devinit, + devshutdown, dupattach, dupwalk, dupstat, diff --git a/emu/port/devdynld.c b/emu/port/devdynld.c index 68084707..b447d797 100644 --- a/emu/port/devdynld.c +++ b/emu/port/devdynld.c @@ -119,7 +119,7 @@ devload(char *path) { int i; Dyndev *l; - Dev *dev; + Dev *dev, *curdev; char devname[32]; l = dlload(path, _exporttab, dyntabsize(_exporttab)); @@ -131,8 +131,11 @@ devload(char *path) dev = dynimport(l->o, devname, signof(*dev)); if(dev == nil) error("no devtab"); - if(devno(dev->dc, 1) >= 0) + curdev = devtabget(dev->dc, 1); + if(curdev != nil){ + devtabput(curdev); error("device loaded"); + } for(i = 0; devtab[i] != nil; i++) ; if(i >= ndevs || devtab[i+1] != nil) @@ -321,7 +324,9 @@ Dev dynlddevtab = { DEVCHAR, "dynld", + devreset, devinit, + devshutdown, dlattach, dlwalk, dlstat, diff --git a/emu/port/devdynldx.c b/emu/port/devdynldx.c index 738b9ed5..400f71ec 100644 --- a/emu/port/devdynldx.c +++ b/emu/port/devdynldx.c @@ -341,7 +341,9 @@ Dev dynlddevtab = { DEVCHAR, "dynld", + devreset, devinit, + devshutdown, dlattach, dlwalk, dlstat, diff --git a/emu/port/deveia-posix.c b/emu/port/deveia-posix.c index 5db8ae86..9674260d 100644 --- a/emu/port/deveia-posix.c +++ b/emu/port/deveia-posix.c @@ -444,20 +444,22 @@ eiawstat(Chan *c, uchar *dp, int n) } Dev eiadevtab = { - Devchar, - Devname, - - eiainit, - eiaattach, - eiawalk, - eiastat, - eiaopen, - devcreate, - eiaclose, - eiaread, - devbread, - eiawrite, - devbwrite, - devremove, - eiawstat + Devchar, + Devname, + + devreset, + eiainit, + devshutdown, + eiaattach, + eiawalk, + eiastat, + eiaopen, + devcreate, + eiaclose, + eiaread, + devbread, + eiawrite, + devbwrite, + devremove, + eiawstat }; diff --git a/emu/port/devenv.c b/emu/port/devenv.c index 9f56ce7d..71f75d08 100644 --- a/emu/port/devenv.c +++ b/emu/port/devenv.c @@ -237,7 +237,9 @@ Dev envdevtab = { 'e', "env", + devreset, devinit, + devshutdown, envattach, envwalk, envstat, diff --git a/emu/port/devfs-posix.c b/emu/port/devfs-posix.c index bd1d9a94..e6f1c703 100644 --- a/emu/port/devfs-posix.c +++ b/emu/port/devfs-posix.c @@ -123,7 +123,7 @@ fsattach(char *spec) FS(c)->uid = stbuf.st_uid; FS(c)->mode = stbuf.st_mode; lock(&l); - c->dev = devno++; + c->devno = devno++; unlock(&l); if (!emptystr(spec)){ FS(c)->spec = "/"; @@ -162,7 +162,7 @@ fswalk(Chan *c, Chan *nc, char **name, int nname) } if(nc == nil){ nc = devclone(c); - nc->type = 0; + /* nc->dev remains nil for now */ alloc = 1; } wq->clone = nc; @@ -203,8 +203,9 @@ fswalk(Chan *c, Chan *nc, char **name, int nname) wq->clone = nil; }else if(wq->clone){ nc->aux = smalloc(sizeof(Fsinfo)); - nc->type = c->type; - if (nname) { + devtabincref(c->dev); + nc->dev = c->dev; + if(nname) { FS(nc)->gid = stbuf.st_gid; FS(nc)->uid = stbuf.st_uid; FS(nc)->mode = stbuf.st_mode; @@ -1036,7 +1037,9 @@ Dev fsdevtab = { 'U', "fs", + devreset, devinit, + devshutdown, fsattach, fswalk, fsstat, diff --git a/emu/port/devindir.c b/emu/port/devindir.c index 9c214927..b23e12cf 100644 --- a/emu/port/devindir.c +++ b/emu/port/devindir.c @@ -30,6 +30,8 @@ Dev indirdevtab = { '*', "indir", + devreset, devinit, + devshutdown, indirattach, }; diff --git a/emu/port/devip.c b/emu/port/devip.c index e70d7dc3..d68cf172 100644 --- a/emu/port/devip.c +++ b/emu/port/devip.c @@ -148,7 +148,7 @@ ip3gen(Chan *c, int i, Dir *dp) Conv *cv; char *p; - cv = ipfs[c->dev]->p[PROTO(c->qid)]->conv[CONV(c->qid)]; + cv = ipfs[c->devno]->p[PROTO(c->qid)]->conv[CONV(c->qid)]; if(cv->owner == nil) kstrdup(&cv->owner, eve); mkqid(&q, QID(PROTO(c->qid), CONV(c->qid), i), 0, QTFILE); @@ -207,7 +207,7 @@ ip1gen(Chan *c, int i, Dir *dp) Fs *f; extern ulong kerndate; - f = ipfs[c->dev]; + f = ipfs[c->devno]; prot = 0664; mkqid(&q, QID(0, 0, i), 0, QTFILE); @@ -219,7 +219,7 @@ ip1gen(Chan *c, int i, Dir *dp) break; case Qndb: p = "ndb"; - len = strlen(ipfs[c->dev]->ndb); + len = strlen(ipfs[c->devno]->ndb); break; /* case Qiproute: p = "iproute"; @@ -252,13 +252,13 @@ ipgen(Chan *c, char *name, Dirtab *tab, int x, int s, Dir *dp) USED(name); USED(tab); USED(x); - f = ipfs[c->dev]; + f = ipfs[c->devno]; switch(TYPE(c->qid)) { case Qtopdir: if(s == DEVDOTDOT){ mkqid(&q, QID(0, 0, Qtopdir), 0, QTDIR); - sprint(up->genbuf, "#I%lud", c->dev); + sprint(up->genbuf, "#I%ud", c->devno); devdir(c, q, up->genbuf, 0, network, 0555, dp); return 1; } @@ -280,7 +280,7 @@ ipgen(Chan *c, char *name, Dirtab *tab, int x, int s, Dir *dp) case Qprotodir: if(s == DEVDOTDOT){ mkqid(&q, QID(0, 0, Qtopdir), 0, QTDIR); - sprint(up->genbuf, "#I%lud", c->dev); + sprint(up->genbuf, "#I%ud", c->devno); devdir(c, q, up->genbuf, 0, network, 0555, dp); return 1; } @@ -356,7 +356,7 @@ ipattach(char *spec) c = devattach('I', spec); mkqid(&c->qid, QID(0, 0, Qtopdir), 0, QTDIR); - c->dev = 0; + c->devno = 0; return c; } @@ -391,7 +391,7 @@ ipopen(Chan *c, int omode) perm = m2p[omode&3]; - f = ipfs[c->dev]; + f = ipfs[c->devno]; switch(TYPE(c->qid)) { default: @@ -526,7 +526,7 @@ ipclose(Chan *c) { Fs *f; - f = ipfs[c->dev]; + f = ipfs[c->devno]; switch(TYPE(c->qid)) { case Qdata: case Qctl: @@ -546,7 +546,7 @@ ipread(Chan *ch, void *a, long n, vlong off) Fs *f; ulong offset = off; - f = ipfs[ch->dev]; + f = ipfs[ch->devno]; p = a; switch(TYPE(ch->qid)) { @@ -816,7 +816,7 @@ ipwrite(Chan *ch, void *a, long n, vlong off) Cmdbuf *cb; Fs *f; - f = ipfs[ch->dev]; + f = ipfs[ch->devno]; switch(TYPE(ch->qid)) { default: @@ -932,7 +932,7 @@ ipwstat(Chan *c, uchar *dp, int n) Proto *p; Fs *f; - f = ipfs[c->dev]; + f = ipfs[c->devno]; switch(TYPE(c->qid)) { default: error(Eperm); @@ -1071,7 +1071,9 @@ Dev ipdevtab = { 'I', "ip", + devreset, ipinit, + devshutdown, ipattach, ipwalk, ipstat, diff --git a/emu/port/devlogfs.c b/emu/port/devlogfs.c index 2d867496..823a5a1c 100755 --- a/emu/port/devlogfs.c +++ b/emu/port/devlogfs.c @@ -778,7 +778,6 @@ devlogfswalk(Chan *c, Chan *nc, char **name, int nname) clone = 0; if(nc == nil){ nc = devclone(c); - nc->type = 0; SPLITPATH(c->qid.path, c->qid.type, instance, qid, qt); if(DATAQID(qid, qt)) nc->aux = devlogfsget(instance); @@ -791,7 +790,8 @@ devlogfswalk(Chan *c, Chan *nc, char **name, int nname) } else if (clone) { wq->clone = nc; - nc->type = c->type; + devtabincref(nc->dev); + nc->dev = c->dev; } #ifdef CALLTRACE print("devlogfswalk(c = 0x%.8lux, nc = 0x%.8lux, name = 0x%.8lux, nname = %d) - return\n", @@ -804,8 +804,8 @@ static int devlogfsstat(Chan *c, uchar *dp, int n) { #ifdef CALLTRACE - print("devlogfsstat(c = 0x%.8lux, dp = 0x%.8lux n= %d)\n", - (ulong)c, (ulong)dp, n); + print("devlogfsstat(c = %.8p, dp = %.8p n= %d)\n", + c, dp, n); #endif return devstat(c, dp, n, 0, 0, devlogfsgen); } @@ -1503,7 +1503,9 @@ Dev logfsdevtab = { #ifndef EMU devreset, #endif + devreset, devinit, + devshutdown, #ifndef EMU devshutdown, #endif diff --git a/emu/port/devmem.c b/emu/port/devmem.c index 78f772c6..02768c04 100644 --- a/emu/port/devmem.c +++ b/emu/port/devmem.c @@ -468,7 +468,9 @@ Dev memdevtab = { '%', "mem", + devreset, devinit, + devshutdown, memattach, memwalk, memstat, diff --git a/emu/port/devmnt.c b/emu/port/devmnt.c index 6a18dd0a..f539933f 100644 --- a/emu/port/devmnt.c +++ b/emu/port/devmnt.c @@ -164,7 +164,7 @@ mntversion(Chan *c, char *version, int msize, int returnlen) c->offset += k; unlock(&c->l); - l = devtab[c->type]->write(c, msg, k, oo); + l = c->dev->write(c, msg, k, oo); if(l < k){ lock(&c->l); @@ -174,7 +174,7 @@ mntversion(Chan *c, char *version, int msize, int returnlen) } /* message sent; receive and decode reply */ - k = devtab[c->type]->read(c, msg, 8192+IOHDRSZ, c->offset); + k = c->dev->read(c, msg, 8192+IOHDRSZ, c->offset); if(k <= 0) error("EOF receiving fversion reply"); @@ -368,7 +368,7 @@ mntchan(void) c = devattach('M', 0); lock(&mntalloc.l); - c->dev = mntalloc.id++; + c->devno = mntalloc.id++; unlock(&mntalloc.l); if(c->mchan) @@ -405,9 +405,8 @@ mntwalk(Chan *c, Chan *nc, char **name, int nname) nc = devclone(c); /* * Until the other side accepts this fid, we can't mntclose it. - * Therefore set type to 0 for now; rootclose is known to be safe. + * nc->dev remains nil for now. */ - nc->type = 0; alloc = 1; } wq->clone = nc; @@ -440,7 +439,8 @@ mntwalk(Chan *c, Chan *nc, char **name, int nname) /* move new fid onto mnt device and update its qid */ if(wq->clone != nil){ if(wq->clone != c){ - wq->clone->type = c->type; + devtabincref(c->dev); + wq->clone->dev = c->dev; wq->clone->mchan = c->mchan; incref(&c->mchan->r); } @@ -794,7 +794,7 @@ mountio(Mnt *m, Mntrpc *r) n = convS2M(&r->request, r->rpc, m->msize); if(n < 0) panic("bad message type in mountio"); - if(devtab[m->c->type]->write(m->c, r->rpc, n, 0) != n) + if(m->c->dev->write(m->c, r->rpc, n, 0) != n) error(Emountrpc); /* r->stime = fastticks(nil); */ r->reqlen = n; @@ -830,7 +830,7 @@ doread(Mnt *m, int len) Block *b; while(qlen(m->q) < len){ - b = devtab[m->c->type]->bread(m->c, m->msize, 0); + b = m->c->dev->bread(m->c, m->msize, 0); if(b == nil) return -1; if(blocklen(b) == 0){ @@ -1151,7 +1151,7 @@ mntchk(Chan *c) /* * Was it closed and reused (was error(Eshutdown); now, it can't happen) */ - if(m->id == 0 || m->id >= c->dev) + if(m->id == 0 || m->id >= c->devno) panic("mntchk 3: can't happen"); return m; @@ -1167,11 +1167,11 @@ mntdirfix(uchar *dirbuf, Chan *c) { uint r; - r = devtab[c->type]->dc; + r = c->dev->dc; dirbuf += BIT16SZ; /* skip count */ PBIT16(dirbuf, r); dirbuf += BIT16SZ; - PBIT32(dirbuf, c->dev); + PBIT32(dirbuf, c->devno); } int @@ -1187,7 +1187,9 @@ Dev mntdevtab = { 'M', "mnt", + devreset, mntinit, + devshutdown, mntattach, mntwalk, mntstat, diff --git a/emu/port/devpipe.c b/emu/port/devpipe.c index 32c16ab6..29e75c79 100644 --- a/emu/port/devpipe.c +++ b/emu/port/devpipe.c @@ -99,7 +99,6 @@ pipeattach(char *spec) c->qid.vers = 0; c->qid.type = QTDIR; c->aux = p; - c->dev = 0; return c; } @@ -311,7 +310,7 @@ piperead(Chan *c, void *va, long n, vlong junk) } static Block* -pipebread(Chan *c, long n, ulong offset) +pipebread(Chan *c, long n, vlong offset) { Pipe *p; @@ -368,7 +367,7 @@ pipewrite(Chan *c, void *va, long n, vlong junk) } static long -pipebwrite(Chan *c, Block *bp, ulong junk) +pipebwrite(Chan *c, Block *bp, vlong junk) { long n; Pipe *p; @@ -444,7 +443,9 @@ Dev pipedevtab = { '|', "pipe", + devreset, pipeinit, + devshutdown, pipeattach, pipewalk, pipestat, diff --git a/emu/port/devpointer.c b/emu/port/devpointer.c index 30bad028..789d1bac 100644 --- a/emu/port/devpointer.c +++ b/emu/port/devpointer.c @@ -288,7 +288,9 @@ Dev pointerdevtab = { 'm', "pointer", + devreset, devinit, + devshutdown, pointerattach, pointerwalk, pointerstat, diff --git a/emu/port/devprof.c b/emu/port/devprof.c index 86d6d962..5a88eabd 100644 --- a/emu/port/devprof.c +++ b/emu/port/devprof.c @@ -801,7 +801,9 @@ Dev profdevtab = { 'P', "prof", + devreset, devinit, + devshutdown, profattach, profwalk, profstat, diff --git a/emu/port/devprog.c b/emu/port/devprog.c index 8ee6a75b..24f37888 100644 --- a/emu/port/devprog.c +++ b/emu/port/devprog.c @@ -480,10 +480,10 @@ progfdprint(Chan *c, int fd, int w, char *s, int ns) if(w == 0) w = progqidwidth(c); - n = snprint(s, ns, "%3d %.2s %C %4ld (%.16llux %*lud %.2ux) %5ld %8lld %s\n", + n = snprint(s, ns, "%3d %.2s %C %4d (%.16llux %*lud %.2ux) %5ld %8lld %s\n", fd, &"r w rw"[(c->mode&3)<<1], - devtab[c->type]->dc, c->dev, + c->dev->dc, c->devno, c->qid.path, w, c->qid.vers, c->qid.type, c->iounit, c->offset, c->name->s); return n; @@ -610,6 +610,16 @@ calldepth(REG *reg) return n; } +int +stringutflen(String *s) +{ + int n; + n = s->len; + if(n >= 0) + return n; + return runenlen(s->Srune, -n); +} + static int progheap(Heapqry *hq, char *va, int count, ulong offset) { @@ -716,8 +726,8 @@ progheap(Heapqry *hq, char *va, int count, ulong offset) return -1; n += snprint(va+n, count-n, "%d.", abs(ss->len)); str = string2c(ss); - len = strlen(str); - if(count-n < len) + len = stringutflen(ss); + if(len >= count-n) len = count-n; if(len > 0) { memmove(va+n, str, len); @@ -892,11 +902,11 @@ progread(Chan *c, void *va, long n, vlong offset) } int2flag(mw->cm->mflag, flag); if(strcmp(mw->cm->to->name->s, "#M") == 0){ - i = snprint(a, n, "mount %s %s %s %s\n", flag, + i = snprint(a, n, "mount %s %q %q %q\n", flag, mw->cm->to->mchan->name->s, mw->mh->from->name->s, mw->cm->spec? mw->cm->spec : ""); }else - i = snprint(a, n, "bind %s %s %s\n", flag, + i = snprint(a, n, "bind %s %q %q\n", flag, mw->cm->to->name->s, mw->mh->from->name->s); poperror(); release(); @@ -1491,7 +1501,9 @@ Dev progdevtab = { 'p', "prog", + devreset, devinit, + devshutdown, progattach, progwalk, progstat, diff --git a/emu/port/devroot.c b/emu/port/devroot.c index 695d151c..3aea7eac 100644 --- a/emu/port/devroot.c +++ b/emu/port/devroot.c @@ -134,7 +134,9 @@ Dev rootdevtab = { '/', "root", + devreset, devinit, + devshutdown, rootattach, rootwalk, rootstat, diff --git a/emu/port/devsign.c b/emu/port/devsign.c index ba44e286..e05194ef 100644 --- a/emu/port/devsign.c +++ b/emu/port/devsign.c @@ -424,7 +424,9 @@ Dev signdevtab = { 0x03A3, /* L'Σ', /* U+03A3 */ "sign", + devreset, devinit, + devshutdown, signattach, signwalk, signstat, diff --git a/emu/port/devsnarf.c b/emu/port/devsnarf.c index 4778c130..3701ccc3 100644 --- a/emu/port/devsnarf.c +++ b/emu/port/devsnarf.c @@ -145,7 +145,9 @@ Dev snarfdevtab = { '^', "snarf", + devreset, devinit, + devshutdown, snarfattach, snarfwalk, snarfstat, diff --git a/emu/port/devsrv.c b/emu/port/devsrv.c index f655bf96..fd252e1e 100644 --- a/emu/port/devsrv.c +++ b/emu/port/devsrv.c @@ -662,7 +662,7 @@ srvf2c(char *dir, char *file, Sys_FileIO *io) error(Efilename); c.c = namec(dir, Aaccess, 0, 0); - if((c.c->qid.type&QTDIR) == 0 || devtab[c.c->type]->dc != 's') + if((c.c->qid.type&QTDIR) == 0 || c.c->dev->dc != 's') error("directory not a srv device"); s = c.c->aux; @@ -709,7 +709,9 @@ Dev srvdevtab = { 's', "srv", + devreset, srvinit, + devshutdown, srvattach, srvwalk, srvstat, diff --git a/emu/port/devssl.c b/emu/port/devssl.c index c8c16fc3..ca224a7f 100644 --- a/emu/port/devssl.c +++ b/emu/port/devssl.c @@ -375,7 +375,7 @@ ensure(Dstate *s, Block **l, int n) } while(sofar < n){ - bl = devtab[s->c->type]->bread(s->c, Maxdmsg, 0); + bl = s->c->dev->bread(s->c, Maxdmsg, 0); if(bl == 0) error(Ehungup); *l = bl; @@ -466,7 +466,7 @@ qtake(Block **l, int n, int discard) } static Block* -sslbread(Chan *c, long n, ulong offset) +sslbread(Chan *c, long n, vlong offset) { volatile struct { Dstate *s; } s; volatile struct { int nc; } nc; @@ -623,7 +623,7 @@ randfill(uchar *buf, int len) * use SSL record format, add in count and digest or encrypt */ static long -sslbwrite(Chan *c, Block *b, ulong offset) +sslbwrite(Chan *c, Block *b, vlong offset) { volatile struct { Dstate *s; } s; volatile struct { Block *b; } bb; @@ -719,7 +719,7 @@ sslbwrite(Chan *c, Block *b, ulong offset) s.s->out.mid++; m = BLEN(nb); - devtab[s.s->c->type]->bwrite(s.s->c, nb, s.s->c->offset); + s.s->c->dev->bwrite(s.s->c, nb, s.s->c->offset); s.s->c->offset += m; } qunlock(&s.s->out.q); @@ -1133,6 +1133,27 @@ out: } +Dev ssldevtab = { + 'D', + "ssl", + + devreset, + sslinit, + devshutdown, + sslattach, + sslwalk, + sslstat, + sslopen, + devcreate, + sslclose, + sslread, + sslbread, + sslwrite, + sslbwrite, + devremove, + sslwstat +}; + static Block* encryptb(Dstate *s, Block *b, int offset) { @@ -1343,6 +1364,10 @@ buftochan(char *p) if(fd < 0) error(Ebadarg); c = fdtochan(up->env->fgrp, fd, -1, 0, 1); /* error check and inc ref */ + if(c->dev == &ssldevtab){ + cclose(c); + error("cannot ssl encrypt devssl files"); + } return c; } @@ -1420,22 +1445,3 @@ dsnew(Chan *ch, Dstate **pp) ch->qid.vers = 0; ch->qid.type = QTFILE; } - -Dev ssldevtab = { - 'D', - "ssl", - - sslinit, - sslattach, - sslwalk, - sslstat, - sslopen, - devcreate, - sslclose, - sslread, - sslbread, - sslwrite, - sslbwrite, - devremove, - sslwstat -}; diff --git a/emu/port/devtab.c b/emu/port/devtab.c new file mode 100644 index 00000000..69c5f7b2 --- /dev/null +++ b/emu/port/devtab.c @@ -0,0 +1,94 @@ +#include "dat.h" +#include "fns.h" +#include "error.h" + +extern Dev* devtab[]; + +void +devtabreset(void) +{ + int i; + + for(i = 0; devtab[i] != nil; i++) + devtab[i]->reset(); +} + +void +devtabinit(void) +{ + int i; + + for(i = 0; devtab[i] != nil; i++) + devtab[i]->init(); +} + +void +devtabshutdown(void) +{ + int i; + + /* + * Shutdown in reverse order. + */ + for(i = 0; devtab[i] != nil; i++) + ; + for(i--; i >= 0; i--) + devtab[i]->shutdown(); +} + + +Dev* +devtabget(int dc, int user) +{ + int i; + + for(i = 0; devtab[i] != nil; i++){ + if(devtab[i]->dc == dc) + return devtab[i]; + } + + if(user == 0) + panic("devtabget %C\n", dc); + + return nil; +} + +Dev* +devbyname(char *name) +{ + int i; + + for(i = 0; devtab[i] != nil; i++) + if(strcmp(devtab[i]->name, name) == 0) + return devtab[i]; + return nil; +} + +long +devtabread(Chan*, void* buf, long n, vlong off) +{ + int i; + Dev *dev; + char *alloc, *e, *p; + + alloc = malloc(READSTR); + if(alloc == nil) + error(Enomem); + + p = alloc; + e = p + READSTR; + for(i = 0; devtab[i] != nil; i++){ + dev = devtab[i]; + p = seprint(p, e, "#%C %s\n", dev->dc, dev->name); + } + + if(waserror()){ + free(alloc); + nexterror(); + } + n = readstr(off, buf, n, alloc); + free(alloc); + poperror(); + + return n; +} diff --git a/emu/port/devtinyfs.c b/emu/port/devtinyfs.c index 33689745..a096a7eb 100644 --- a/emu/port/devtinyfs.c +++ b/emu/port/devtinyfs.c @@ -185,7 +185,7 @@ readdata(Tfs *fs, ulong bno, uchar *buf, int *lenp) { if(bno >= fs->nblocks) return 0; - if(devtab[fs->c->type]->read(fs->c, buf, Blen, Blen*bno) != Blen) + if(fs->c->dev->read(fs->c, buf, Blen, Blen*bno) != Blen) error(Eio); return validdata(fs, buf, lenp); } @@ -212,7 +212,7 @@ writedata(Tfs *fs, ulong bno, ulong next, uchar *buf, int len, int last) memmove(md.data, buf, len); md.sum = 0 - checksum((uchar*)&md); - if(devtab[fs->c->type]->write(fs->c, &md, Blen, Blen*bno) != Blen) + if(fs->c->dev->write(fs->c, &md, Blen, Blen*bno) != Blen) error(Eio); } @@ -233,7 +233,7 @@ writedir(Tfs *fs, Tfile *f) PUTS(md->pin, f->pin); md->sum = 0 - checksum(buf); - if(devtab[fs->c->type]->write(fs->c, buf, Blen, Blen*f->bno) != Blen) + if(fs->c->dev->write(fs->c, buf, Blen, Blen*f->bno) != Blen) error(Eio); } @@ -248,7 +248,7 @@ freeblocks(Tfs *fs, ulong bno, ulong bend) while(bno != bend && bno != Notabno){ mapclr(fs, bno); - if(devtab[fs->c->type]->read(fs->c, buf, Blen, Blen*bno) != Blen) + if(fs->c->dev->read(fs->c, buf, Blen, Blen*bno) != Blen) break; md = validdata(fs, buf, 0); if(md == 0) @@ -272,7 +272,7 @@ freefile(Tfs *fs, Tfile *f, ulong bend) /* change file type to free on medium */ if(f->bno != Notabno){ memset(buf, 0x55, Blen); - devtab[fs->c->type]->write(fs->c, buf, Blen, Blen*f->bno); + fs->c->dev->write(fs->c, buf, Blen, Blen*f->bno); mapclr(fs, f->bno); } @@ -364,7 +364,7 @@ tfsinit(Tfs *fs) Mdir *mdir; Mdata *mdata; - n = devtab[fs->c->type]->stat(fs->c, dbuf, sizeof(dbuf)); + n = fs->c->dev->stat(fs->c, dbuf, sizeof(dbuf)); n = convM2D(dbuf, n, &d, nil); if(n <= 0) error("cannot stat tinyfs medium"); @@ -382,7 +382,7 @@ tfsinit(Tfs *fs) /* find files */ for(bno = 0; bno < fs->nblocks; bno++){ - n = devtab[fs->c->type]->read(fs->c, buf, Blen, Blen*bno); + n = fs->c->dev->read(fs->c, buf, Blen, Blen*bno); if(n != Blen) break; @@ -412,7 +412,7 @@ tfsinit(Tfs *fs) freefile(fs, f, bno); break; } - n = devtab[fs->c->type]->read(fs->c, buf, Blen, Blen*bno); + n = fs->c->dev->read(fs->c, buf, Blen, Blen*bno); if(n != Blen){ freefile(fs, f, bno); break; @@ -453,7 +453,7 @@ tinyfsgen(Chan *c, char *name, Dirtab *tab, int ntab, int i, Dir *dp) USED(ntab); USED(tab); - fs = &tinyfs.fs[c->dev]; + fs = &tinyfs.fs[c->devno]; if(i >= fs->nf) return -1; qid.vers = 0; @@ -525,7 +525,7 @@ tinyfsattach(char *spec) poperror(); c = devattach('F', spec); - c->dev = fs - tinyfs.fs; + c->devno = fs - tinyfs.fs; c->qid.type = QTDIR; c->qid.vers = 0; @@ -538,12 +538,12 @@ tinyfswalk(Chan *c, Chan *nc, char **name, int nname) Tfs *fs; Walkqid *wq; - fs = &tinyfs.fs[c->dev]; + fs = &tinyfs.fs[c->devno]; qlock(&fs->ql); wq = devwalk(c, nc, name, nname, 0, 0, tinyfsgen); if(wq != nil && (nc = wq->clone) != nil && nc->qid.path != Qdir){ - fs = &tinyfs.fs[nc->dev]; + fs = &tinyfs.fs[nc->devno]; fs->f[nc->qid.path-1].r++; } qunlock(&fs->ql); @@ -562,7 +562,7 @@ tinyfsopen(Chan *c, int omode) Tfile *f; volatile struct { Tfs *fs; } rock; - rock.fs = &tinyfs.fs[c->dev]; + rock.fs = &tinyfs.fs[c->devno]; if(c->qid.type & QTDIR){ if(omode != OREAD) @@ -600,7 +600,7 @@ tinyfscreate(Chan *c, char *name, int omode, ulong perm) USED(perm); - rock.fs = &tinyfs.fs[c->dev]; + rock.fs = &tinyfs.fs[c->devno]; qlock(&rock.fs->ql); if(waserror()){ @@ -625,7 +625,7 @@ tinyfsremove(Chan *c) if(c->qid.path == Qdir) error(Eperm); - fs = &tinyfs.fs[c->dev]; + fs = &tinyfs.fs[c->devno]; f = &fs->f[c->qid.path-1]; qlock(&fs->ql); freefile(fs, f, Notabno); @@ -639,7 +639,7 @@ tinyfsclose(Chan *c) Tfile *f, *nf; int i; - rock.fs = &tinyfs.fs[c->dev]; + rock.fs = &tinyfs.fs[c->devno]; qlock(&rock.fs->ql); @@ -703,7 +703,7 @@ tinyfsread(Chan *c, void *a, long n, vlong offset) return devdirread(c, a, n, 0, 0, tinyfsgen); p = a; - rock.fs = &tinyfs.fs[c->dev]; + rock.fs = &tinyfs.fs[c->devno]; f = &rock.fs->f[c->qid.path-1]; if(offset >= f->length) return 0; @@ -783,7 +783,7 @@ tinyfswrite(Chan *c, void *a, long n, vlong offset) return 0; p = a; - rock.fs = &tinyfs.fs[c->dev]; + rock.fs = &tinyfs.fs[c->devno]; f = &rock.fs->f[c->qid.path-1]; qlock(&rock.fs->ql); @@ -879,7 +879,9 @@ Dev tinyfsdevtab = { 'F', "tinyfs", + devreset, devinit, + devshutdown, tinyfsattach, tinyfswalk, tinyfsstat, diff --git a/emu/port/devtk.c b/emu/port/devtk.c index 6f31967b..e8982632 100644 --- a/emu/port/devtk.c +++ b/emu/port/devtk.c @@ -158,8 +158,9 @@ Dev tkdevtab = { L'τ', "tk", -// devreset, + devreset, devinit, + devshutdown, tkattach, // devdetach, devclone, diff --git a/emu/port/dynldc.c b/emu/port/dynldc.c index 2237f7ab..a33cac82 100644 --- a/emu/port/dynldc.c +++ b/emu/port/dynldc.c @@ -16,9 +16,10 @@ readfc(void *a, void *buf, long nbytes) if(waserror()) return -1; - nbytes = devtab[c->type]->read(c, buf, nbytes, c->offset); + nbytes = c->dev->read(c, buf, nbytes, c->offset); poperror(); return nbytes; + devshutdown, } static vlong diff --git a/emu/port/exportfs.c b/emu/port/exportfs.c index 1feae7ae..b9d7da58 100644 --- a/emu/port/exportfs.c +++ b/emu/port/exportfs.c @@ -200,7 +200,7 @@ exreadn(Chan *c, void *buf, int n) if(waserror()) return -1; for(nr = 0; nr < n;){ - t = devtab[c->type]->read(c, (char*)buf+nr, n-nr, 0); + t = c->dev->read(c, (char*)buf+nr, n-nr, 0); if(t <= 0) break; nr += t; @@ -636,7 +636,7 @@ exreply(Exq *q, char *who) print("%s %ld -> %F\n", who, up->pid, r); if(!waserror()){ - devtab[fs->io->type]->write(fs->io, q->buf, n, 0); + fs->io->dev->write(fs->io, q->buf, n, 0); poperror(); } } @@ -738,7 +738,7 @@ exmount(Chan *c, Mhead **mp, int doname) Cname *oname; nc.nc = nil; - if((c->flag & COPEN) == 0 && findmount(&nc.nc, mp, c->type, c->dev, c->qid)){ + if((c->flag & COPEN) == 0 && findmount(&nc.nc, mp, c->dev->dc, c->devno, c->qid)){ if(waserror()){ cclose(nc.nc); nexterror(); @@ -934,7 +934,7 @@ Exopen(Export *fs, Fcall *t, Fcall *r) else putmhead(m); - c = devtab[c->type]->open(c, t->mode); + c = c->dev->open(c, t->mode); if(t->mode & ORCLOSE) c->flag |= CRCLOSE; @@ -1001,7 +1001,7 @@ Excreate(Export *fs, Fcall *t, Fcall *r) poperror(); c.c->name = oname; } - devtab[c.c->type]->create(c.c, t->name, t->mode, t->perm); + c.c->dev->create(c.c, t->name, t->mode, t->perm); c.c->name = addelem(c.c->name, t->name); if(t->mode & ORCLOSE) c.c->flag |= CRCLOSE; @@ -1043,7 +1043,7 @@ Exread(Export *fs, Fcall *t, Fcall *r) error(Emode); if(c->mode != OREAD && c->mode != ORDWR) error(Eaccess); - if(t->count < 0 || t->count > fs->msize-IOHDRSZ) + if((int)t->count < 0 || t->count > fs->msize-IOHDRSZ) error(Ecount); if(t->offset < 0) error(Enegoff); @@ -1077,7 +1077,7 @@ Exread(Export *fs, Fcall *t, Fcall *r) lock(cl); c->offset = off; unlock(cl); - n = devtab[c->type]->read(c, r->data, n, off); + n = c->dev->read(c, r->data, n, off); lock(cl); c->offset += n; unlock(cl); @@ -1113,11 +1113,11 @@ Exwrite(Export *fs, Fcall *t, Fcall *r) error(Eaccess); if(c->qid.type & QTDIR) error(Eisdir); - if(t->count < 0 || t->count > fs->msize-IOHDRSZ) + if((int)t->count < 0 || t->count > fs->msize-IOHDRSZ) error(Ecount); if(t->offset < 0) error(Enegoff); - r->count = devtab[c->type]->write(c, t->data, t->count, t->offset); + r->count = c->dev->write(c, t->data, t->count, t->offset); poperror(); Exputfid(fs, f); return nil; @@ -1139,7 +1139,7 @@ Exstat(Export *fs, Fcall *t, Fcall *r) Exputfid(fs, f); return up->env->errstr; } - n = devtab[c->type]->stat(c, r->stat, r->nstat); + n = c->dev->stat(c, r->stat, r->nstat); if(n <= BIT16SZ) error(Eshortstat); r->nstat = n; @@ -1171,7 +1171,7 @@ Exwstat(Export *fs, Fcall *t, Fcall *r) cclose(c); nexterror(); } - devtab[c->type]->wstat(c, t->stat, t->nstat); + c->dev->wstat(c, t->stat, t->nstat); poperror(); cclose(c); @@ -1197,20 +1197,24 @@ Exremove(Export *fs, Fcall *t, Fcall *r) } c = exmount(f->chan, nil, 0); if(waserror()){ - c->type = 0; /* see below */ + if(c->dev != nil){ + devtabput(c->dev); + c->dev = nil; /* see below */ + } cclose(c); nexterror(); } - devtab[c->type]->remove(c); + c->dev->remove(c); poperror(); poperror(); /* * chan is already clunked by remove. * however, we need to recover the chan, - * and follow sysremove's lead in making it point to root. + * and follow sysremove's lead in making its dev nil. */ - c->type = 0; + devtabput(c->dev); + c->dev = nil; cclose(c); f->attached = 0; diff --git a/emu/port/fns.h b/emu/port/fns.h index 545b578f..e394a8b3 100644 --- a/emu/port/fns.h +++ b/emu/port/fns.h @@ -37,19 +37,27 @@ int cmount(Chan*, Chan*, int, char*); Chan* createdir(Chan*, Mhead*); void cunmount(Chan*, Chan*); int decref(Ref*); -long devbwrite(Chan*, Block*, ulong); +long devbwrite(Chan*, Block*, vlong); void devcreate(Chan*, char*, int, ulong); void devdir(Chan*, Qid, char*, long, char*, long, Dir*); long devdirread(Chan*, char*, long, Dirtab*, int, Devgen*); void devinit(void); -int devno(int, int); Dev* devbyname(char*); void devpermcheck(char*, ulong, int); void devremove(Chan*); +void devreset(void); +void devshutdown(void); int devstat(Chan*, uchar*, int, Dirtab*, int, Devgen*); +Dev* devtabget(int, int); +#define devtabincref(d) +void devtabinit(void); +#define devtabput(d) +void devtabreset(void); +long devtabread(Chan*, void*, long, vlong); +void devtabshutdown(void); int devwstat(Chan*, uchar*, int); Chan* devattach(int, char*); -Block* devbread(Chan*, long, ulong); +Block* devbread(Chan*, long, vlong); Chan* devclone(Chan*); Devgen devgen; Chan* devopen(Chan*, int, Dirtab*, int, Devgen*); @@ -72,7 +80,7 @@ void excinit(void); void exhausted(char*); int export(int, char*, int); Chan* fdtochan(Fgrp*, int, int, int, int); -int findmount(Chan**, Mhead**, int, int, Qid); +int findmount(Chan**, Mhead**, int, uint, Qid); void freeb(Block*); void freeblist(Block*); void freeskey(Signerkey*); diff --git a/emu/port/sysfile.c b/emu/port/sysfile.c index 8159ae2d..8a0fbd23 100644 --- a/emu/port/sysfile.c +++ b/emu/port/sysfile.c @@ -92,9 +92,9 @@ kchanio(void *vc, void *buf, int n, int mode) return -1; if(mode == OREAD) - r = devtab[c->type]->read(c, buf, n, c->offset); + r = c->dev->read(c, buf, n, c->offset); else - r = devtab[c->type]->write(c, buf, n, c->offset); + r = c->dev->write(c, buf, n, c->offset); lock(&c->l); c->offset += r; @@ -255,7 +255,7 @@ kfstat(int fd, uchar *buf, int n) return -1; } c.c = fdtochan(up->env->fgrp, fd, -1, 0, 1); - devtab[c.c->type]->stat(c.c, buf, n); + c.c->dev->stat(c.c, buf, n); poperror(); cclose(c.c); return n; @@ -351,14 +351,12 @@ kfversion(int fd, uint msize, char *vers, uint arglen) int kpipe(int fd[2]) { - Dev *d; Fgrp *f; Chan *c[2]; static char *names[] = {"data", "data1"}; f = up->env->fgrp; - d = devtab[devno('|', 0)]; c[0] = namec("#|", Atodir, 0, 0); c[1] = 0; fd[0] = -1; @@ -379,8 +377,8 @@ kpipe(int fd[2]) error(Egreg); if(walk(&c[1], &names[1], 1, 1, nil) < 0) error(Egreg); - c[0] = d->open(c[0], ORDWR); - c[1] = d->open(c[1], ORDWR); + c[0] = c[0]->dev->open(c[0], ORDWR); + c[1] = c[1]->dev->open(c[1], ORDWR); fd[0] = newfd(c[0]); if(fd[0] < 0) error(Enofd); @@ -403,7 +401,7 @@ kfwstat(int fd, uchar *buf, int n) } validstat(buf, n); c.c = fdtochan(up->env->fgrp, fd, -1, 1, 1); - n = devtab[c.c->type]->wstat(c.c, buf, n); + n = c.c->dev->wstat(c.c, buf, n); poperror(); cclose(c.c); return n; @@ -455,11 +453,13 @@ kmount(int fd, int afd, char *old, int flags, char *spec) volatile struct { Chan *c; } c0; volatile struct { Chan *c; } bc; volatile struct { Chan *c; } ac; + volatile struct { Dev *d; } dev; Mntparam mntparam; ac.c = nil; bc.c = nil; c0.c = nil; + dev.d = nil; if(waserror()) { cclose(ac.c); cclose(bc.c); @@ -473,7 +473,14 @@ kmount(int fd, int afd, char *old, int flags, char *spec) mntparam.authchan = ac.c; mntparam.spec = spec; mntparam.flags = flags; - c0.c = devtab[devno('M', 0)]->attach((char*)&mntparam); + dev.d = devtabget('M', 0); + if(waserror()){ + devtabput(dev.d); + nexterror(); + } + c0.c = dev.d->attach((char*)&mntparam); + poperror(); + devtabput(dev.d); r = bindmount(c0.c, old, flags, spec); poperror(); @@ -562,10 +569,10 @@ unionread(Chan *c, void *va, long n) if(mount->to && !waserror()) { if(c->umc == nil){ c->umc = cclone(mount->to); - c->umc = devtab[c->umc->type]->open(c->umc, OREAD); + c->umc = c->umc->dev->open(c->umc, OREAD); } - nr = devtab[c->umc->type]->read(c->umc, va, n, c->umc->offset); + nr = c->umc->dev->read(c->umc, va, n, c->umc->offset); if(nr < 0) nr = 0; /* dev.c can return -1 */ c->umc->offset += nr; @@ -641,7 +648,7 @@ rread(int fd, void *va, long n, vlong *offp) } unionrewind(c.c); } - n = devtab[c.c->type]->read(c.c, va, n, off); + n = c.c->dev->read(c.c, va, n, off); lock(cl); c.c->offset += n; unlock(cl); @@ -676,16 +683,20 @@ kremove(char *path) c.c = namec(path, Aremove, 0, 0); if(waserror()){ - c.c->type = 0; /* see below */ + if(c.c->dev != nil){ + devtabput(c.c->dev); + c.c->dev = nil; /* see below */ + } cclose(c.c); nexterror(); } - devtab[c.c->type]->remove(c.c); + c.c->dev->remove(c.c); /* * Remove clunks the fid, but we need to recover the Chan - * so fake it up. rootclose() is known to be a nop. + * so discard the association with the current device. */ - c.c->type = 0; + devtabput(c.c->dev); + c.c->dev = nil; poperror(); cclose(c.c); @@ -708,7 +719,7 @@ kseek(int fd, vlong off, int whence) nexterror(); } - if(devtab[c->type]->dc == '|') + if(c->dev->dc == '|') error(Eisstream); switch(whence) { @@ -801,7 +812,7 @@ kstat(char *path, uchar *buf, int n) return -1; } c.c = namec(path, Aaccess, 0, 0); - devtab[c.c->type]->stat(c.c, buf, n); + c.c->dev->stat(c.c, buf, n); poperror(); cclose(c.c); return 0; @@ -847,7 +858,7 @@ rwrite(int fd, void *va, long n, vlong *offp) } if(off < 0) error(Enegoff); - m = devtab[c.c->type]->write(c.c, va, n, off); + m = c.c->dev->write(c.c, va, n, off); poperror(); if(offp == nil && m < n){ @@ -887,7 +898,7 @@ kwstat(char *path, uchar *buf, int n) } validstat(buf, n); c.c = namec(path, Aaccess, 0, 0); - n = devtab[c.c->type]->wstat(c.c, buf, n); + n = c.c->dev->wstat(c.c, buf, n); poperror(); cclose(c.c); return n; @@ -914,7 +925,7 @@ chandirstat(Chan *c) free(d); return nil; } - n = devtab[c->type]->stat(c, buf, nd); + n = c->dev->stat(c, buf, nd); poperror(); if(n < BIT16SZ){ free(d); diff --git a/emu/port/uqid.c b/emu/port/uqid.c index bd43db3d..fbe07c01 100644 --- a/emu/port/uqid.c +++ b/emu/port/uqid.c @@ -29,7 +29,7 @@ uqidlook(Uqid **tab, Chan *c, vlong path) Uqid **hp, *q; for(hp = &tab[uqidhash(path)]; (q = *hp) != nil; hp = &q->next) - if(q->type == c->type && q->dev == c->dev && q->oldpath == path) + if(q->dc == c->dev->dc && q->devno == c->devno && q->oldpath == path) break; return hp; } @@ -65,8 +65,8 @@ uqidalloc(Uqidtab *tab, Chan *c) error(Enomem); } q->r.ref = 1; - q->type = c->type; - q->dev = c->dev; + q->dc = c->dev->dc; + q->devno = c->devno; q->oldpath = c->qid.path; q->newpath = c->qid.path; while(uqidexists(tab->qids, q->newpath)){ |
