Commit Diff


commit - 869875b48b4455937fdddb7c98fbff7699c1effb
commit + 9ec57f8b9e8a243ca94fbdef0ed571b823a095b7
blob - c9d4f55dd5ac8ab0f213d029a322fac434ea1be3
blob + 45041e6652a9c0b830a1f2e3ed604a9a8233f652
--- src/cmd/9pfuse/main.c
+++ src/cmd/9pfuse/main.c
@@ -855,6 +855,7 @@ fusereadlink(FuseMsg *m)
  * are stored in m->d,nd,d0.
  */
 int canpack(Dir*, uvlong, uchar**, uchar*);
+Dir *dotdirs(CFid*);
 void
 fusereaddir(FuseMsg *m)
 {
@@ -871,9 +872,8 @@ fusereaddir(FuseMsg *m)
 	if(in->offset == 0){
 		fsseek(ff->fid, 0, 0);
 		free(ff->d0);
-		ff->d0 = nil;
-		ff->d = nil;
-		ff->nd = 0;
+		ff->d0 = ff->d = dotdirs(ff->fid);
+		ff->nd = 2;
 	}
 	n = in->size;
 	if(n > fusemaxwrite)
@@ -906,6 +906,31 @@ out:			
 	free(buf);
 }
 
+/*
+ * Fuse assumes that it can always read two directory entries.
+ * If it gets just one, it will double it in the dirread results.
+ * Thus if a directory contains just "a", you see "a" twice.
+ * Adding . as the first directory entry works around this.
+ * We could add .. too, but it isn't necessary.
+ */
+Dir*
+dotdirs(CFid *f)
+{
+	Dir *d;
+	CFid *f1;
+
+	d = emalloc(2*sizeof *d);
+	d[0].name = ".";
+	d[0].qid = fsqid(f);
+	d[1].name = "..";
+	f1 = fswalk(f, "..");
+	if(f1){
+		d[1].qid = fsqid(f1);
+		fsclose(f1);
+	}
+	return d;
+}
+
 int
 canpack(Dir *d, uvlong off, uchar **pp, uchar *ep)
 {