M gnot/fns.h => gnot/fns.h +1 -0
@@ 70,6 70,7 @@ void fprestore(FPsave*);
void fpregrestore(char*);
void freeb(Block*);
int freebroken(void);
+void freechan(Chan*);
void freenextmod(PTE*);
void freepage(Orig*, int);
void freepte(Orig*);
M port/chan.c => port/chan.c +15 -11
@@ 101,11 101,13 @@ loop:
void
freechan(Chan *c)
{
- c->flag = CFREE;
- lock(&chanalloc);
- c->next = chanalloc.free;
- chanalloc.free = c;
- unlock(&chanalloc);
+ if(decref(c) == 0){
+ c->flag = CFREE;
+ lock(&chanalloc);
+ c->next = chanalloc.free;
+ chanalloc.free = c;
+ unlock(&chanalloc);
+ }
}
void
@@ 114,13 116,15 @@ close(Chan *c)
if(c->flag & CFREE)
panic("close");
if(decref(c) == 0){
- if(waserror()) {
- freechan(c);
- nexterror();
+ if(!waserror()) {
+ (*devtab[c->type].close)(c);
+ poperror();
}
- (*devtab[c->type].close)(c);
- freechan(c);
- poperror();
+ c->flag = CFREE;
+ lock(&chanalloc);
+ c->next = chanalloc.free;
+ chanalloc.free = c;
+ unlock(&chanalloc);
}
}
M port/dev.c => port/dev.c +14 -3
@@ 107,10 107,21 @@ devwalk(Chan *c, char *name, Dirtab *tab, int ntab, Devgen *gen)
}
}
-int devclwalk(Chan *c, Chan *nc, char *name, Dirtab *tab, int ntab, Devgen *gen)
+Chan*
+devclwalk(Chan *c, char *name)
{
- c = devclone(c, nc);
- return devwalk(c, name, tab, ntab, gen);
+ Chan *nc;
+
+ nc = 0;
+ if(waserror()){
+ if(nc)
+ close(nc);
+ return 0;
+ }
+ nc = (*devtab[c->type].clone)(c, 0);
+ (*devtab[nc->type].walk)(nc, name);
+ poperror();
+ return nc;
}
void
M port/devmnt.c => port/devmnt.c +27 -0
@@ 388,6 388,33 @@ mntwalk(Chan *c, char *name)
return found;
}
+Chan *
+mntclwalk(Chan *c, char *name)
+{
+ Mnt *m;
+ Mnthdr *mh;
+ Chan *nc;
+
+ nc = newchan();
+ m = mntdev(c->dev, 0);
+ mh = mhalloc();
+ mh->thdr.type = Tclwalk;
+ mh->thdr.fid = c->fid;
+ mh->thdr.newfid = nc->fid;
+ strcpy(mh->thdr.name, name);
+ if(waserror()){ /* BUG: can check type of error? */
+ freechan(nc);
+ nc = 0;
+ goto Out;
+ }
+ mntxmit(m, mh);
+ nc->qid = mh->rhdr.qid;
+ poperror();
+ Out:
+ mhfree(mh);
+ return nc;
+}
+
void
mntstat(Chan *c, char *dp)
{
M port/fcall.c => port/fcall.c +14 -0
@@ 92,6 92,12 @@ convS2M(Fcall *f, char *ap)
SHORT(fid);
STRING(stat, sizeof(f->stat));
break;
+
+ case Tclwalk:
+ SHORT(fid);
+ SHORT(newfid);
+ STRING(name, sizeof(f->name));
+ break;
/*
*/
case Rnop:
@@ 117,6 123,7 @@ convS2M(Fcall *f, char *ap)
SHORT(fid);
break;
+ case Rclwalk:
case Rwalk:
SHORT(fid);
LONG(qid.path);
@@ 284,6 291,12 @@ convM2S(char *ap, Fcall *f, int n)
SHORT(fid);
STRING(stat, sizeof(f->stat));
break;
+
+ case Tclwalk:
+ SHORT(fid);
+ SHORT(newfid);
+ STRING(name, sizeof(f->name));
+ break;
/*
*/
case Rnop:
@@ 310,6 323,7 @@ convM2S(char *ap, Fcall *f, int n)
break;
case Rwalk:
+ case Rclwalk:
SHORT(fid);
LONG(qid.path);
LONG(qid.vers);
M power/fns.h => power/fns.h +1 -0
@@ 70,6 70,7 @@ void flushmmu(void);
void forkmod(Seg*, Seg*, Proc*);
void freeb(Block*);
int freebroken(void);
+void freechan(Chan*);
void freepage(Orig*, int);
void freepte(Orig*);
void freesegs(int);
M ss/fns.h => ss/fns.h +1 -0
@@ 77,6 77,7 @@ void fprestore(FPsave*);
void fpregrestore(char*);
void freeb(Block*);
int freebroken(void);
+void freechan(Chan*);
void freenextmod(PTE*);
void freepage(Orig*, int);
void freepte(Orig*);