From 0d5dc81693a0775c2c84736fc888643b2096b19a Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 30 Dec 1999 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1999-12-30 --- ip/devip.c | 38 ++++++++++++++------------ pc/devastar.c | 5 ++++ pc/devata.c | 5 ++++ pc/devi82365.c | 5 ++++ pc/devlpt.c | 5 ++++ pc/devusb.c | 12 +++++++++ port/chan.c | 67 +++++++++++++--------------------------------- port/dev.c | 16 +++++++++-- port/devbridge.c | 32 +++++++++++----------- port/devdraw.c | 40 ++++++++++++++------------- port/devdup.c | 4 +++ port/devenv.c | 5 ++++ port/devmnt.c | 10 ++++--- port/devmntstats.c | 5 ++++ port/devpipe.c | 5 ++++ port/devproc.c | 11 ++++---- port/devroot.c | 3 +-- port/devsd.c | 5 ++++ port/devsdp.c | 32 +++++++++++----------- port/devsrv.c | 5 ++++ port/devssl.c | 17 +++++++++++- port/devtinyfs.c | 7 ++++- port/netif.c | 17 ++++++++++-- port/portdat.h | 2 ++ 24 files changed, 223 insertions(+), 130 deletions(-) diff --git a/ip/devip.c b/ip/devip.c index 7166ec51e941987a6fa572c108d67ebb496ae1b0..bf84ede87d6f12c478ea279b97998496da4b5286 100644 --- a/ip/devip.c +++ b/ip/devip.c @@ -172,11 +172,17 @@ ipgen(Chan *c, Dirtab*, int, int s, Dir *dp) switch(TYPE(c->qid)) { case Qtopdir: + if(s == DEVDOTDOT){ + q = (Qid){QID(0, 0, Qtopdir)|CHDIR, 0}; + sprint(name, "#I%lud", c->dev); + devdir(c, q, name, 0, network, 0555, dp); + return 1; + } if(s < f->np) { if(f->p[s]->connect == nil) return 0; /* protocol with no user interface */ q = (Qid){QID(s, 0, Qprotodir)|CHDIR, 0}; - devdir(c, q, f->p[s]->name, 0, network, CHDIR|0555, dp); + devdir(c, q, f->p[s]->name, 0, network, 0555, dp); return 1; } s -= f->np; @@ -189,11 +195,17 @@ ipgen(Chan *c, Dirtab*, int, int s, Dir *dp) case Qipselftab: return ip1gen(c, TYPE(c->qid), dp); case Qprotodir: + if(s == DEVDOTDOT){ + q = (Qid){QID(0, 0, Qtopdir)|CHDIR, 0}; + sprint(name, "#I%lud", c->dev); + devdir(c, q, name, 0, network, 0555, dp); + return 1; + } if(s < f->p[PROTO(c->qid)]->ac) { cv = f->p[PROTO(c->qid)]->conv[s]; sprint(name, "%d", s); q = (Qid){QID(PROTO(c->qid), s, Qconvdir)|CHDIR, 0}; - devdir(c, q, name, 0, cv->owner, CHDIR|0555, dp); + devdir(c, q, name, 0, cv->owner, 0555, dp); return 1; } s -= f->p[PROTO(c->qid)]->ac; @@ -202,6 +214,12 @@ ipgen(Chan *c, Dirtab*, int, int s, Dir *dp) case Qstats: return ip2gen(c, TYPE(c->qid), dp); case Qconvdir: + if(s == DEVDOTDOT){ + s = PROTO(c->qid); + q = (Qid){QID(s, 0, Qprotodir)|CHDIR, 0}; + devdir(c, q, f->p[s]->name, 0, network, 0555, dp); + return 1; + } return ip3gen(c, s+Qconvbase, dp); case Qctl: case Qdata: @@ -285,21 +303,7 @@ ipclone(Chan* c, Chan* nc) static int ipwalk(Chan* c, char* name) { - if(strcmp(name, "..") != 0) - return devwalk(c, name, nil, 0, ipgen); - - switch(TYPE(c->qid)){ - case Qtopdir: - case Qprotodir: - c->qid = (Qid){QID(0, 0, Qtopdir)|CHDIR, 0}; - break; - case Qconvdir: - c->qid = (Qid){QID(PROTO(c->qid), 0, Qprotodir)|CHDIR, 0}; - break; - default: - panic("ipwalk %lux", c->qid.path); - } - return 1; + return devwalk(c, name, nil, 0, ipgen); } static void diff --git a/pc/devastar.c b/pc/devastar.c index 9614fc49c983f25043c53aa134f3ed62615adb74..88a1d144da7483ee9c6b0b2ab3aa64273f31b014 100644 --- a/pc/devastar.c +++ b/pc/devastar.c @@ -347,6 +347,11 @@ astargen(Chan *c, Dirtab *, int , int i, Dir *db) sofar = 0; + if(i == DEVDOTDOT){ + devdir(c, (Qid){CHDIR, 0}, "#G", 0, eve, 0555, db); + return 1; + } + for(dev = 0; dev < nastar; dev++){ if(sofar == i){ sprint(db->name, "astar%dmem", astar[dev]->id); diff --git a/pc/devata.c b/pc/devata.c index ef9433010d74879a8387621ee980ba8a3646da12..31e54c7d3157b149d74a0a73342d9071b5146d4a 100644 --- a/pc/devata.c +++ b/pc/devata.c @@ -248,6 +248,11 @@ atagen(Chan* c, Dirtab*, int, int s, Dir* dirp) Partition *pp; vlong l; + if(s == DEVDOTDOT){ + devdir(c, (Qid){CHDIR, 0}, "#H", 0, eve, 0555, dirp); + return 1; + } + qid.vers = 0; drive = s/Npart; s = s % Npart; diff --git a/pc/devi82365.c b/pc/devi82365.c index db20701a2d4659e12bb408d93fe581a3cea19d2d..c13384fcff9e6875149ce262ff8aeeccbee58c56 100644 --- a/pc/devi82365.c +++ b/pc/devi82365.c @@ -482,6 +482,11 @@ pcmgen(Chan *c, Dirtab *, int , int i, Dir *dp) Slot *pp; char name[NAMELEN]; + if(i == DEVDOTDOT){ + devdir(c, (Qid){CHDIR, 0}, "#y", 0, eve, 0555, dp); + return 1; + } + if(i >= Nents*nslot) return -1; slotno = i/Nents; diff --git a/pc/devlpt.c b/pc/devlpt.c index 761f0249f56ed7919d66f72a1b75c3aeda541766..23a0e3e854a24699d56fb21776ef8aecc6e2ac85 100644 --- a/pc/devlpt.c +++ b/pc/devlpt.c @@ -59,6 +59,11 @@ lptgen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp) Qid qid; char name[NAMELEN]; + if(i == DEVDOTDOT){ + sprint(name, "#L%lud", c->dev+1); + devdir(c, (Qid){CHDIR, 0}, name, 0, eve, 0555, dp); + return 1; + } if(tab==0 || i>=ntab) return -1; tab += i; diff --git a/pc/devusb.c b/pc/devusb.c index 47ded81f75bc02eef628778bd56495b1f1d16987..d84049fc689ab65c02ea424c96c263c86634c4ec 100644 --- a/pc/devusb.c +++ b/pc/devusb.c @@ -1389,6 +1389,10 @@ usbgen(Chan *c, Dirtab*, int, int s, Dir *dp) * Top level directory contains the name of the device. */ if(c->qid.path == CHDIR){ + if(s == DEVDOTDOT){ + devdir(c, (Qid){CHDIR, 0}, "#U", 0, eve, 0555, dp); + return 1; + } if(s == 0){ devdir(c, (Qid){CHDIR|Q2nd, 0}, "usb", 0, eve, 0555, dp); return 1; @@ -1401,6 +1405,10 @@ usbgen(Chan *c, Dirtab*, int, int s, Dir *dp) */ t = QID(c->qid); if(t < Q3rd){ + if(s == DEVDOTDOT){ + devdir(c, (Qid){CHDIR, 0}, "#U", 0, eve, 0555, dp); + return 1; + } if(s < nelem(usbdir2)){ tab = &usbdir2[s]; devdir(c, tab->qid, tab->name, tab->length, eve, tab->perm, dp); @@ -1423,6 +1431,10 @@ usbgen(Chan *c, Dirtab*, int, int s, Dir *dp) */ path = c->qid.path&~(CHDIR|QMASK); /* slot component */ q.vers = c->qid.vers; + if(s == DEVDOTDOT){ + devdir(c, (Qid){CHDIR|Q2nd, 0}, "usb", 0, eve, 0555, dp); + return 1; + } if(s < nelem(usbdir3)){ Dirtab *tab = &usbdir3[s]; q.path = path | tab->qid.path; diff --git a/port/chan.c b/port/chan.c index 959b73df6d3022387f7f5c60a33b756238c88e14..8ca705a9b1863b09ff343197906e83f083a4d485 100644 --- a/port/chan.c +++ b/port/chan.c @@ -19,7 +19,7 @@ struct }chanalloc; #define SEP(c) ((c) == 0 || (c) == '/') -void cleancname(Cname*, int); +void cleancname(Cname*); int incref(Ref *r) @@ -483,7 +483,7 @@ updatecname(Chan *c, char *name, int dotdot) c->name = addelem(c->name, name); if(dotdot){ - cleancname(c->name, c->name->s[0]=='#'); /* could be cheaper */ + cleancname(c->name); /* could be cheaper */ c = undomount(c); } return c; @@ -644,50 +644,25 @@ saveregisters(void) * In place, rewrite name to compress multiple /, eliminate ., and process .. */ void -cleancname(Cname *n, int offset) +cleancname(Cname *n) { - char *p, *q, *dotdot, *name; - int rooted; + char *p; - name = n->s+offset; - rooted = name[0] == '/'; + if(n->s[0] == '#'){ + p = strchr(n->s, '/'); + if(p == nil) + return; + cleanname(p); - /* - * invariants: - * p points at beginning of path element we're considering. - * q points just past the last path element we wrote (no slash). - * dotdot points just past the point where .. cannot backtrack - * any further (no slash). - */ - p = q = dotdot = name+rooted; - while(*p) { - if(p[0] == '/') /* null element */ - p++; - else if(p[0] == '.' && SEP(p[1])) - p += 1; /* don't count the separator in case it is nul */ - else if(p[0] == '.' && p[1] == '.' && SEP(p[2])) { - p += 2; - if(q > dotdot) { /* can backtrack */ - while(--q > dotdot && *q != '/') - ; - } else if(!rooted) { /* /.. is / but ./../ is .. */ - if(q != name) - *q++ = '/'; - *q++ = '.'; - *q++ = '.'; - dotdot = q; - } - } else { /* real path element */ - if(q != name+rooted) - *q++ = '/'; - while((*q = *p) != '/' && *q != 0) - p++, q++; - } - } - if(q == name) /* empty string is really ``.'' */ - *q++ = '.'; - *q = '\0'; - n->len = (q-name) + offset; + /* + * The correct name is #i rather than #i/, + * but the correct name of #/ is #/. + */ + if(strcmp(p, "/")==0 && n->s[1] != '/') + *p = '\0'; + }else + cleanname(n->s); + n->len = strlen(n->s); } /* @@ -911,12 +886,8 @@ namec(char *name, int amode, int omode, ulong perm) poperror(); - /* peculiar workaround for #/ */ if(newname){ - if(cname->s[0]=='#' && cname->s[1]=='/') - cleancname(cname, 1); - else - cleancname(cname, 0); + cleancname(cname); cnameclose(c->name); c->name = cname; }else diff --git a/port/dev.c b/port/dev.c index 24e98f17f9c6f537ff1ad9775877bbb20b5b527f..c5dd77414cd1fa975e4938b2b2abaa413da9d1e9 100644 --- a/port/dev.c +++ b/port/dev.c @@ -42,12 +42,19 @@ devdir(Chan *c, Qid qid, char *n, vlong length, char *user, long perm, Dir *db) memmove(db->gid, eve, NAMELEN); } +// +// the zeroth element of the table MUST be the directory itself for .. +// int devgen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp) { - if(tab==0 || i>=ntab) + if(tab==0) return -1; - tab += i; + if(i!=DEVDOTDOT){ + if(i>=ntab) + return -1; + tab += i; + } devdir(c, tab->qid, tab->name, tab->length, eve, tab->perm, dp); return 1; } @@ -111,6 +118,11 @@ devwalk(Chan *c, char *name, Dirtab *tab, int ntab, Devgen *gen) isdir(c); if(name[0]=='.' && name[1]==0) return 1; + if(name[0]=='.' && name[1]=='.' && name[2]==0){ + (*gen)(c, tab, ntab, DEVDOTDOT, &dir); + c->qid = dir.qid; + return 1; + } for(i=0;; i++) { switch((*gen)(c, tab, ntab, i, &dir)){ case -1: diff --git a/port/devbridge.c b/port/devbridge.c index 248f1bb494e8fc55bc8b62c05d4861fce2bb7c92..8905be7e762ea11c53101ffec498546fe49c30d6 100644 --- a/port/devbridge.c +++ b/port/devbridge.c @@ -222,21 +222,6 @@ bridgeattach(char* spec) static int bridgewalk(Chan *c, char *name) { - if(strcmp(name, "..") == 0){ - switch(TYPE(c->qid)){ - case Qtopdir: - case Qbridgedir: - c->qid = (Qid){CHDIR|Qtopdir, 0}; - break; - case Qportdir: - c->qid = (Qid){CHDIR|Qbridgedir, 0}; - break; - default: - panic("bridgewalk %lux", c->qid.path); - } - return 1; - } - return devwalk(c, name, 0, 0, bridgegen); } @@ -431,6 +416,23 @@ bridgegen(Chan *c, Dirtab*, int, int s, Dir *dp) Dirtab *dt; Qid qid; + if(s == DEVDOTDOT){ + switch(TYPE(c->qid)){ + case Qtopdir: + case Qbridgedir: + snprint(buf, "#B%d", c->dev); + devdir(c, (Qid){CHDIR|Qtopdir, 0}, buf, 0, eve, 0555, dp); + break; + case Qportdir: + sprint(buf, "bridge%ld", c->dev); + devdir(c, (Qid){CHDIR|Qbridgedir, 0}, buf, 0, eve, 0555, dp); + break; + default: + panic("bridgewalk %lux", c->qid.path); + } + return 1; + } + switch(type) { default: // non directory entries end up here diff --git a/port/devdraw.c b/port/devdraw.c index e38db3ab2eebf6de1db2bec417afe7fcecf96fc7..8718d73d556d41eaeea201df3059af5604deb0f7 100644 --- a/port/devdraw.c +++ b/port/devdraw.c @@ -162,6 +162,7 @@ extern void flushmemscreen(Rectangle); void drawmesg(Client*, void*, int); void drawuninstall(Client*, int); void drawfreedimage(DImage*); + Client* drawclientofpath(ulong); static char Enodrawimage[] = "unknown id for draw image"; static char Enodrawscreen[] = "unknown id for draw screen"; @@ -194,6 +195,26 @@ drawgen(Chan *c, Dirtab *tab, int x, int s, Dir *dp) USED(tab, x); q.vers = 0; + if(s == DEVDOTDOT){ + switch(QID(c->qid)){ + case Qtopdir: + case Q2nd: + devdir(c, (Qid){CHDIR|Qtopdir, 0}, "#i", 0, eve, 0500, dp); + break; + case Q3rd: + cl = drawclientofpath(c->qid.path); + if(cl == nil) + strcpy(buf, "??"); + else + sprint(buf, "%d", cl->clientid); + devdir(c, (Qid){CHDIR|Q2nd, 0}, buf, 0, eve, 0500, dp); + break; + default: + panic("drawwalk %lux", c->qid.path); + } + return 1; + } + /* * Top level directory contains the name of the device. */ @@ -855,25 +876,6 @@ drawwalk(Chan *c, char *name) { if(screendata.bdata == nil) error("no frame buffer"); - if(strcmp(name, "..") == 0){ - switch(QID(c->qid)){ - case Qtopdir: - return 1; - case Q2nd: - c->qid = (Qid){CHDIR|Qtopdir, 0}; - break; - case Q3rd: - c->qid = (Qid){CHDIR|Q2nd, 0}; - break; - default: - panic("drawwalk %lux", c->qid.path); - } -print("drawwalk: ..?\n"); -// op = c->path; -// c->path = ptenter(&syspt, op, name); -// decref(op); - return 1; - } return devwalk(c, name, 0, 0, drawgen); } diff --git a/port/devdup.c b/port/devdup.c index f0e5d0e1e7e9e750d261d35e76e83abfc7898d33..229e5cc523cbfc38f5dfd02b6e3ed128506960a1 100644 --- a/port/devdup.c +++ b/port/devdup.c @@ -13,6 +13,10 @@ dupgen(Chan *c, Dirtab*, int, int s, Dir *dp) Chan *f; static int perm[] = { 0400, 0200, 0600, 0 }; + if(s == DEVDOTDOT){ + devdir(c, c->qid, "#d", 0, eve, 0555, dp); + return 1; + } if(s > fgrp->maxfd) return -1; if((f=fgrp->fd[s]) == 0) diff --git a/port/devenv.c b/port/devenv.c index f712265ca5016eda835e6a6aba85381c003560ad..f576f9a0edac64740fe918e49ba92ed24a91c974 100644 --- a/port/devenv.c +++ b/port/devenv.c @@ -17,6 +17,11 @@ envgen(Chan *c, Dirtab*, int, int s, Dir *dp) Egrp *eg; Evalue *e; + if(s == DEVDOTDOT){ + devdir(c, c->qid, "#e", 0, eve, 0775, dp); + return 1; + } + eg = up->egrp; qlock(eg); diff --git a/port/devmnt.c b/port/devmnt.c index 3364545b3ac7428330567f70e04b913742b91701..3f4ef76f5a5aa5870affc6282b1a25844f70a061 100644 --- a/port/devmnt.c +++ b/port/devmnt.c @@ -747,9 +747,10 @@ mountmux(Mnt *m, Mntrpc *r) lock(m); l = &m->queue; for(q = *l; q; q = q->list) { - if(q->request.tag == r->reply.tag - || q->flushed && q->flushtag == r->reply.tag) { + if((q->flushed==0 && q->request.tag == r->reply.tag) + || (q->flushed && q->flushtag == r->reply.tag)) { *l = q->list; + q->done = 1; unlock(m); if(q != r) { /* @@ -760,7 +761,6 @@ mountmux(Mnt *m, Mntrpc *r) q->rpc = r->rpc; r->rpc = dp; q->reply = r->reply; - q->done = 1; if(mntstats != nil) (*mntstats)(q->request.type, m->c, q->stime, @@ -787,6 +787,10 @@ mntflush(Mnt *m, Mntrpc *r) Fcall flush; lock(m); + if(r->done){ + unlock(m); + return 1; + } r->flushtag = m->flushtag++; if(m->flushtag == Tagend) m->flushtag = m->flushbase; diff --git a/port/devmntstats.c b/port/devmntstats.c index f4cfbc545632ac3269e0bffd56c839f236f839d0..120ea4c8157f7ee49d7dc90070bbc0d11818e9ed 100644 --- a/port/devmntstats.c +++ b/port/devmntstats.c @@ -97,6 +97,11 @@ mntstatsgen(Chan *c, Dirtab*, int, int i, Dir *dp) char name[NAMELEN]; Mntstats *m; + if(i == DEVDOTDOT){ + devdir(c, (Qid){CHDIR,0}, "#z", 0, eve, 0555, dp); + return 1; + } + m = &msalloc.all[i]; if(i > Nms || m->inuse == 0) return -1; diff --git a/port/devpipe.c b/port/devpipe.c index d0acffb43e23882d4d5726e2e8661fd83c30435c..65814362d05bb463bd0bb97cfa5d391cd0cf419c 100644 --- a/port/devpipe.c +++ b/port/devpipe.c @@ -114,6 +114,11 @@ pipegen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp) { int id; + if(i == DEVDOTDOT){ + devdir(c, c->qid, "#|", 0, eve, CHDIR|0555, dp); + return 1; + } + id = NETID(c->qid.path); if(i > 1) id++; diff --git a/port/devproc.c b/port/devproc.c index 11fc17dc8edb21acdae05da724005f6eef5d357c..9aaa6876fe0a2806ba29c0df68a829eabd63730e 100644 --- a/port/devproc.c +++ b/port/devproc.c @@ -82,6 +82,12 @@ procgen(Chan *c, Dirtab *tab, int, int s, Dir *dp) char buf[NAMELEN]; ulong pid, path, perm, len; + if(s == DEVDOTDOT){ + c->qid.path = CHDIR; + devdir(c, c->qid, "#p", 0, eve, 0555, dp); + return 1; + } + if(c->qid.path == CHDIR){ if(s >= conf.nproc) return -1; @@ -142,11 +148,6 @@ procattach(char *spec) static int procwalk(Chan *c, char *name) { - if(strcmp(name, "..") == 0) { - c->qid.path = CHDIR; - return 1; - } - return devwalk(c, name, 0, 0, procgen); } diff --git a/port/devroot.c b/port/devroot.c index b04d6cbf09d4fa32e5fe766008b8bf06a29c7adc..6f56c0b563b980d159a4e8fd70e489218f05f237 100644 --- a/port/devroot.c +++ b/port/devroot.c @@ -149,7 +149,6 @@ rootread(Chan *c, void *buf, long n, vlong off) ulong t; Dirtab *d; uchar *data; - Recover *r; ulong offset = off; t = c->qid.path & ~CHDIR; @@ -169,7 +168,7 @@ rootread(Chan *c, void *buf, long n, vlong off) } static long -rootwrite(Chan *c, void *buf, long n, vlong) +rootwrite(Chan *c, void*, long, vlong) { switch(c->qid.path & ~CHDIR){ default: diff --git a/port/devsd.c b/port/devsd.c index fa9e4881eda6ca8af1646dcdb807efc15140355d..8bcb7f11f58a037c83ba109c087efaf6ca0b3cc9 100644 --- a/port/devsd.c +++ b/port/devsd.c @@ -79,6 +79,11 @@ sdgen(Chan *c, Dirtab*, int, int s, Dir *dirp) char name[2*NAMELEN]; vlong l; + if(s == DEVDOTDOT){ + devdir(c, qid, "#w", 0, eve, 0555, dirp); + return 1; + } + d = disk; while(s >= d->npart) { s -= d->npart; diff --git a/port/devsdp.c b/port/devsdp.c index e633b6f12ff5429f62656000cd8c781ad79f60b1..38a448a46950c27ec411e702be4aa8fdc6acb67c 100644 --- a/port/devsdp.c +++ b/port/devsdp.c @@ -394,21 +394,6 @@ sdpattach(char* spec) static int sdpwalk(Chan *c, char *name) { - if(strcmp(name, "..") == 0){ - switch(TYPE(c->qid)){ - case Qtopdir: - case Qsdpdir: - c->qid = (Qid){CHDIR|Qtopdir, 0}; - break; - case Qconvdir: - c->qid = (Qid){CHDIR|Qsdpdir, 0}; - break; - default: - panic("sdpwalk %lux", c->qid.path); - } - return 1; - } - return devwalk(c, name, 0, 0, sdpgen); } @@ -728,6 +713,23 @@ sdpgen(Chan *c, Dirtab*, int, int s, Dir *dp) Dirtab *dt; Qid qid; + if(s == DEVDOTDOT){ + switch(TYPE(c->qid)){ + case Qtopdir: + case Qsdpdir: + snprint(buf, sizeof(buf), "#E%d", c->dev); + devdir(c, (Qid){CHDIR|Qtopdir, 0}, buf, 0, eve, 0555, dp); + break; + case Qconvdir: + snprint(buf, sizeof(buf), "%d", s); + devdir(c, (Qid){CHDIR|Qsdpdir, 0}, buf, 0, eve, 0555, dp); + break; + default: + panic("sdpwalk %lux", c->qid.path); + } + return 1; + } + switch(type) { default: // non directory entries end up here diff --git a/port/devsrv.c b/port/devsrv.c index 9987202fe5964863f9f952128bcce8a8bf38d3eb..dc8db5288634e9534d58b97a8e1d8bcc470d3391 100644 --- a/port/devsrv.c +++ b/port/devsrv.c @@ -26,6 +26,11 @@ srvgen(Chan *c, Dirtab*, int, int s, Dir *dp) { Srv *sp; + if(s == DEVDOTDOT){ + devdir(c, c->qid, "#s", 0, eve, 0555, dp); + return 1; + } + qlock(&srvlk); for(sp = srv; sp && s; sp = sp->link) s--; diff --git a/port/devssl.c b/port/devssl.c index 481859924f2327dfb884247d48a2845f483a37f4..d7968a3c6ffe662ea8c3f947248b44fc30b4a6b1 100644 --- a/port/devssl.c +++ b/port/devssl.c @@ -124,12 +124,22 @@ sslgen(Chan *c, Dirtab *d, int nd, int s, Dir *dp) q.vers = 0; switch(TYPE(c->qid)) { case Qtopdir: + if(s == DEVDOTDOT){ + q.path = QID(0, Qtopdir)|CHDIR; + devdir(c, q, "#D", 0, eve, 0555, dp); + return 1; + } if(s > 0) return -1; q.path = QID(0, Qprotodir)|CHDIR; devdir(c, q, "ssl", 0, eve, 0555, dp); return 1; case Qprotodir: + if(s == DEVDOTDOT){ + q.path = QID(0, Qtopdir)|CHDIR; + devdir(c, q, ".", 0, eve, 0555, dp); + return 1; + } if(s < dshiwat) { sprint(name, "%d", s); q.path = QID(s, Qconvdir)|CHDIR; @@ -138,7 +148,7 @@ sslgen(Chan *c, Dirtab *d, int nd, int s, Dir *dp) nm = ds->user; else nm = eve; - devdir(c, q, name, 0, nm, CHDIR|0555, dp); + devdir(c, q, name, 0, nm, 0555, dp); return 1; } if(s > dshiwat) @@ -147,6 +157,11 @@ sslgen(Chan *c, Dirtab *d, int nd, int s, Dir *dp) devdir(c, q, "clone", 0, eve, 0555, dp); return 1; case Qconvdir: + if(s == DEVDOTDOT){ + q.path = QID(0, Qprotodir)|CHDIR; + devdir(c, q, "ssl", 0, eve, 0555, dp); + return 1; + } ds = dstate[CONV(c->qid)]; if(ds != 0) nm = ds->user; diff --git a/port/devtinyfs.c b/port/devtinyfs.c index a77fb7c10260ea975f92a47592acb94d181141b1..ac64d1b20bb8f7d2bf49fc4a6b3938987b592553 100644 --- a/port/devtinyfs.c +++ b/port/devtinyfs.c @@ -452,14 +452,19 @@ tinyfsgen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp) USED(ntab); USED(tab); + qid.vers = 0; fs = &tinyfs.fs[c->dev]; if(i >= fs->nf) return -1; + if(i == DEVDOTDOT){ + qid.path = CHDIR; + devdir(c, qid, ".", 0, eve, 0555, dp); + return 1; + } f = &fs->f[i]; if(f->name[0] == 0) return 0; qid.path = i; - qid.vers = 0; devdir(c, qid, f->name, f->length, eve, 0775, dp); return 1; } diff --git a/port/netif.c b/port/netif.c index 70432e79f87ae698c049d5cfca3f46a7e26cb6b6..e93e0b96741c8f4d30f3fc1d5ea78de64adf95a0 100644 --- a/port/netif.c +++ b/port/netif.c @@ -45,10 +45,14 @@ netifgen(Chan *c, Dirtab *vp, int, int i, Dir *dp) /* top level directory contains the name of the network */ if(c->qid.path == CHDIR){ switch(i){ + case DEVDOTDOT: + q.path = CHDIR; + devdir(c, q, ".", 0, eve, CHDIR|0555, dp); + break; case 0: q.path = CHDIR | N2ndqid; strcpy(buf, nif->name); - devdir(c, q, buf, 0, eve, 0555, dp); + devdir(c, q, buf, 0, eve, CHDIR|0555, dp); break; default: return -1; @@ -60,6 +64,10 @@ netifgen(Chan *c, Dirtab *vp, int, int i, Dir *dp) t = NETTYPE(c->qid.path); if(t == N2ndqid || t == Ncloneqid || t == Naddrqid){ switch(i) { + case DEVDOTDOT: + q.path = CHDIR; + devdir(c, q, ".", 0, eve, CHDIR|0555, dp); + break; case 0: q.path = Ncloneqid; devdir(c, q, "clone", 0, eve, 0666, dp); @@ -76,7 +84,7 @@ netifgen(Chan *c, Dirtab *vp, int, int i, Dir *dp) return 0; q.path = CHDIR|NETQID(i, N3rdqid); sprint(buf, "%d", i); - devdir(c, q, buf, 0, eve, 0555, dp); + devdir(c, q, buf, 0, eve, CHDIR|0555, dp); break; } return 1; @@ -94,6 +102,11 @@ netifgen(Chan *c, Dirtab *vp, int, int i, Dir *dp) perm = 0666; } switch(i){ + case DEVDOTDOT: + q.path = CHDIR | N2ndqid; + strcpy(buf, nif->name); + devdir(c, q, buf, 0, eve, CHDIR|0555, dp); + break; case 0: q.path = NETQID(NETID(c->qid.path), Ndataqid); devdir(c, q, "data", 0, o, perm, dp); diff --git a/port/portdat.h b/port/portdat.h index 0921b97966758e4c38b4896057ac3230cec3708d..490dd3c75931fb1cedb87e0e328f0efea8df9467 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -739,6 +739,8 @@ struct Cmdbuf extern int nsyscall; +#define DEVDOTDOT -1 + #pragma varargck argpos print 1 #pragma varargck argpos snprint 3 #pragma varargck argpos sprint 2