walk: show siblings with the same qid

the code for skipping directory loops in
walk was taken from du, but the desired
behavior for the two programs is differnt;

while du wants to count the total size used,
and double-counting directories would be a
mistake, walk wants to enumerate all finite
paths in a namespace.
This commit is contained in:
Ori Bernstein 2024-12-10 23:14:33 +00:00
parent ace81cb1ae
commit e58df8173f

View file

@ -21,6 +21,7 @@ Dir *dotdir = nil;
Biobuf *bout;
void unsee(Dir*);
int seen(Dir*);
void
@ -114,8 +115,6 @@ walk(char *path, Dir *cf, long depth)
while((n = dirread(fd, &dirs)) > 0){
fe = dirs+n;
for(f = dirs; f < fe; f++){
if(seen(f))
continue;
if(!(f->qid.type & QTDIR)){
if(fflag && depth >= mindepth)
dofile(path, f, 0);
@ -135,8 +134,11 @@ walk(char *path, Dir *cf, long depth)
s_putc(file, '/');
}
s_append(file, f->name);
if(seen(f))
dofile(s_to_c(file), f, 0);
else
walk(s_to_c(file), f, depth+1);
unsee(f);
s_free(file);
}
}
@ -221,7 +223,6 @@ usage(void)
functions, but since they are a no-op and libString needs
a rework, I left them in - BurnZeZ
*/
void
main(int argc, char **argv)
{
@ -275,11 +276,15 @@ main(int argc, char **argv)
cleanname(argv[i]);
slashslash(argv[i]);
}
if((d = dirstat(argv[i])) != nil && ! (d->qid.type & QTDIR)){
if(fflag && !seen(d) && mindepth < 1)
dofile(argv[i], d, 1);
} else
if((d = dirstat(argv[i])) == nil)
continue;
if(d->qid.type & QTDIR){
seen(d);
walk(argv[i], d, 1);
}else{
if(!dflag && !seen(d) && mindepth < 1)
dofile(argv[i], d, 1);
}
free(d);
}
Bterm(bout);
@ -300,6 +305,23 @@ typedef struct
} Cache;
Cache cache[NCACHE];
void
unsee(Dir *dir)
{
Dir *dp;
int i;
Cache *c;
c = &cache[dir->qid.path&(NCACHE-1)];
dp = c->cache;
for(i=0; i<c->n; i++, dp++){
if(dir->qid.path == dp->qid.path &&
dir->type == dp->type &&
dir->dev == dp->dev)
c->cache[i] = c->cache[--c->n];
}
}
int
seen(Dir *dir)
{