diff options
Diffstat (limited to 'src/base/fs/walk.c')
-rw-r--r-- | src/base/fs/walk.c | 43 |
1 files changed, 23 insertions, 20 deletions
diff --git a/src/base/fs/walk.c b/src/base/fs/walk.c index 786a32a..14371f0 100644 --- a/src/base/fs/walk.c +++ b/src/base/fs/walk.c @@ -28,26 +28,25 @@ void fs·walk(fs·Walker *fs) { char *e, *b; - DIR *dir; - int new, fd, ofd, flags; + sys·Info cwd; fs·History *h; - struct dirent *d; - struct stat cwd; - struct fs·Entry *it; + fs·DirEntry *f; + fs·Directory dir; + int new, fd, ofd, flags; flags = 0; if(fs->flags & fs·nolinks) flags |= sys·AtNoFollowLink; /* get info for base relative to current fd */ - if(fstatat(fs->fd, fs->base, &cwd, flags) < 0){ + if(sys·infoat(fs->fd, fs->base, flags, 0, &cwd)){ if(fs->flags & fs·verbose) errorf("stat: %s", fs->path); return; } /* if we hit a file, finish! */ - if(!S_ISDIR(cwd.st_mode)) { + if(!sys·InfoIsFile(cwd.mode)) { fs->func(fs->data, fs->base, fs->path, &cwd); return; } @@ -55,11 +54,15 @@ fs·walk(fs·Walker *fs) /* have we been here before? (cycle detection) */ /* if not, add to our path history */ if(!(fs->flags & fs·nolinks)){ - addentry(fs->hist, (struct Key){.dev=cwd.st_dev, .ino=cwd.st_ino}, &new); + addentry(fs->hist, + (struct Key){ + .dev = ((uint64)cwd.device.major<<32)|((uint64)cwd.device.minor), + .ino = cwd.inode + }, &new + ); if (!new) return; } - /* * operate on directory first if preorder traversal * truncate recursion if callback returns an error code @@ -70,11 +73,11 @@ fs·walk(fs·Walker *fs) } /* open directory */ - if(!fs->max || fs->lev + 1 < fs->max) { + if(!fs->max || fs->lev + 1 < fs->max){ if(sys·openat(fs->fd, fs->base, sys·ORead|sys·OCloseExec|sys·ODirectory, 0, &fd)) errorf("open %s:", fs->path); - if (!(dir=fdopendir(fd))) { + if(fs·openfd(fd, &dir)){ if(fs->flags & fs·verbose) errorf("fdopendir: %s", fs->path); return; @@ -88,13 +91,13 @@ fs·walk(fs·Walker *fs) *fs->end++ = '/'; fs->base = fs->end; - while((d = readdir(dir))) { - if(*d->d_name == '.') - if(d->d_name[1] == 0 || /* . */ - (d->d_name[1] == '.' && d->d_name[2] == 0)) /* .. */ - continue; + while(!fs·read(&dir,&f)){ + if(f->name[0] == '.') + if(f->name[1] == 0 || /* . */ + (f->name[1] == '.' && f->name[2] == 0)) /* .. */ + continue; - fs->end = str·ncopy(fs->base, arrend(fs->path) - fs->base, d->d_name); + fs->end = str·ncopy(fs->base, arrend(fs->path) - fs->base, f->name); fs->lev++; fs·walk(fs); @@ -103,13 +106,13 @@ fs·walk(fs·Walker *fs) *e = 0; fs->fd = ofd; fs->end = e, fs->base = b; - closedir(dir); + fs·close(&dir); } /* operate on directory if postorder (default) traversal */ - if (!(fs->flags & fs·preorder)) + if(!(fs->flags & fs·preorder)) fs->func(fs->data, fs->base, fs->path, &cwd); - if (!fs->lev) + if(!fs->lev) forget(fs->hist); } |