M ip/devip.c => ip/devip.c +21 -17
@@ 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
M pc/devastar.c => pc/devastar.c +5 -0
@@ 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);
M pc/devata.c => pc/devata.c +5 -0
@@ 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;
M pc/devi82365.c => pc/devi82365.c +5 -0
@@ 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;
M pc/devlpt.c => pc/devlpt.c +5 -0
@@ 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;
M pc/devusb.c => pc/devusb.c +12 -0
@@ 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;
M port/chan.c => port/chan.c +19 -48
@@ 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
M port/dev.c => port/dev.c +14 -2
@@ 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:
M port/devbridge.c => port/devbridge.c +17 -15
@@ 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
M port/devdraw.c => port/devdraw.c +21 -19
@@ 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);
}
M port/devdup.c => port/devdup.c +4 -0
@@ 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)
M port/devenv.c => port/devenv.c +5 -0
@@ 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);
M port/devmnt.c => port/devmnt.c +7 -3
@@ 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;
M port/devmntstats.c => port/devmntstats.c +5 -0
@@ 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;
M port/devpipe.c => port/devpipe.c +5 -0
@@ 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++;
M port/devproc.c => port/devproc.c +6 -5
@@ 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);
}
M port/devroot.c => port/devroot.c +1 -2
@@ 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:
M port/devsd.c => port/devsd.c +5 -0
@@ 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;
M port/devsdp.c => port/devsdp.c +17 -15
@@ 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
M port/devsrv.c => port/devsrv.c +5 -0
@@ 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--;
M port/devssl.c => port/devssl.c +16 -1
@@ 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;
M port/devtinyfs.c => port/devtinyfs.c +6 -1
@@ 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;
}
M port/netif.c => port/netif.c +15 -2
@@ 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);
M port/portdat.h => port/portdat.h +2 -0
@@ 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