mirror of
git://git.9front.org/plan9front/plan9front
synced 2025-01-12 11:10:06 +00:00
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:
parent
ace81cb1ae
commit
e58df8173f
1 changed files with 37 additions and 15 deletions
|
@ -21,6 +21,7 @@ Dir *dotdir = nil;
|
||||||
|
|
||||||
Biobuf *bout;
|
Biobuf *bout;
|
||||||
|
|
||||||
|
void unsee(Dir*);
|
||||||
int seen(Dir*);
|
int seen(Dir*);
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -114,29 +115,30 @@ walk(char *path, Dir *cf, long depth)
|
||||||
while((n = dirread(fd, &dirs)) > 0){
|
while((n = dirread(fd, &dirs)) > 0){
|
||||||
fe = dirs+n;
|
fe = dirs+n;
|
||||||
for(f = dirs; f < fe; f++){
|
for(f = dirs; f < fe; f++){
|
||||||
if(seen(f))
|
if(!(f->qid.type & QTDIR)){
|
||||||
continue;
|
|
||||||
if(! (f->qid.type & QTDIR)){
|
|
||||||
if(fflag && depth >= mindepth)
|
if(fflag && depth >= mindepth)
|
||||||
dofile(path, f, 0);
|
dofile(path, f, 0);
|
||||||
} else if(strcmp(f->name, ".") == 0 || strcmp(f->name, "..") == 0){
|
}else if(strcmp(f->name, ".") == 0 || strcmp(f->name, "..") == 0){
|
||||||
warn(". or .. named file: %s/%s", path, f->name);
|
warn(". or .. named file: %s/%s", path, f->name);
|
||||||
} else{
|
}else{
|
||||||
if(depth+1 > maxdepth){
|
if(depth+1 > maxdepth){
|
||||||
dofile(path, f, 0);
|
dofile(path, f, 0);
|
||||||
continue;
|
continue;
|
||||||
} else if(path == dotpath){
|
}else if(path == dotpath){
|
||||||
if((file = s_new()) == nil)
|
if((file = s_new()) == nil)
|
||||||
sysfatal("s_new: %r");
|
sysfatal("s_new: %r");
|
||||||
} else{
|
}else{
|
||||||
if((file = s_copy(path)) == nil)
|
if((file = s_copy(path)) == nil)
|
||||||
sysfatal("s_copy: %r");
|
sysfatal("s_copy: %r");
|
||||||
if(s_len(file) != 1 || *s_to_c(file) != '/')
|
if(s_len(file) != 1 || *s_to_c(file) != '/')
|
||||||
s_putc(file, '/');
|
s_putc(file, '/');
|
||||||
}
|
}
|
||||||
s_append(file, f->name);
|
s_append(file, f->name);
|
||||||
|
if(seen(f))
|
||||||
walk(s_to_c(file), f, depth+1);
|
dofile(s_to_c(file), f, 0);
|
||||||
|
else
|
||||||
|
walk(s_to_c(file), f, depth+1);
|
||||||
|
unsee(f);
|
||||||
s_free(file);
|
s_free(file);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -221,7 +223,6 @@ usage(void)
|
||||||
functions, but since they are a no-op and libString needs
|
functions, but since they are a no-op and libString needs
|
||||||
a rework, I left them in - BurnZeZ
|
a rework, I left them in - BurnZeZ
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
@ -267,7 +268,7 @@ main(int argc, char **argv)
|
||||||
if(argc == 0){
|
if(argc == 0){
|
||||||
dotdir = dirstat(".");
|
dotdir = dirstat(".");
|
||||||
walk(dotpath, dotdir, 1);
|
walk(dotpath, dotdir, 1);
|
||||||
} else for(i=0; i<argc; i++){
|
}else for(i=0; i<argc; i++){
|
||||||
if(strncmp(argv[i], "#/", 2) == 0)
|
if(strncmp(argv[i], "#/", 2) == 0)
|
||||||
slashslash(argv[i]+2);
|
slashslash(argv[i]+2);
|
||||||
else{
|
else{
|
||||||
|
@ -275,11 +276,15 @@ main(int argc, char **argv)
|
||||||
cleanname(argv[i]);
|
cleanname(argv[i]);
|
||||||
slashslash(argv[i]);
|
slashslash(argv[i]);
|
||||||
}
|
}
|
||||||
if((d = dirstat(argv[i])) != nil && ! (d->qid.type & QTDIR)){
|
if((d = dirstat(argv[i])) == nil)
|
||||||
if(fflag && !seen(d) && mindepth < 1)
|
continue;
|
||||||
dofile(argv[i], d, 1);
|
if(d->qid.type & QTDIR){
|
||||||
} else
|
seen(d);
|
||||||
walk(argv[i], d, 1);
|
walk(argv[i], d, 1);
|
||||||
|
}else{
|
||||||
|
if(!dflag && !seen(d) && mindepth < 1)
|
||||||
|
dofile(argv[i], d, 1);
|
||||||
|
}
|
||||||
free(d);
|
free(d);
|
||||||
}
|
}
|
||||||
Bterm(bout);
|
Bterm(bout);
|
||||||
|
@ -300,6 +305,23 @@ typedef struct
|
||||||
} Cache;
|
} Cache;
|
||||||
Cache cache[NCACHE];
|
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
|
int
|
||||||
seen(Dir *dir)
|
seen(Dir *dir)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue