aboutsummaryrefslogtreecommitdiff
path: root/sys/base/fs/walk.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/base/fs/walk.c')
-rw-r--r--sys/base/fs/walk.c119
1 files changed, 0 insertions, 119 deletions
diff --git a/sys/base/fs/walk.c b/sys/base/fs/walk.c
deleted file mode 100644
index d528896..0000000
--- a/sys/base/fs/walk.c
+++ /dev/null
@@ -1,119 +0,0 @@
-#include "internal.h"
-
-#define hash(k) ((int32)k.ino ^ (int32)k.dev)
-#define equal(k1, k2) (k1.ino == k2.ino && k1.dev == k2.dev)
-
-static
-int
-morehistory(fs·History *h, int n)
-{
- SET_GROW(h, struct Key, n, hash, sys·Memory, nil);
-}
-
-static
-int
-addentry(fs·History *h, struct Key key, int *err)
-{
- SET_PUT(h, key, hash, equal, morehistory, err);
-}
-
-static
-void
-forget(fs·History *h)
-{
- if (!h)
- return;
-
- SET_RESET(h);
-}
-
-void
-fs·walk(fs·Walker *fs)
-{
- char *e, *b;
- DIR *dir;
- int new, fd, ofd, flags;
- fs·History *h;
- struct dirent *d;
- io·Stat cwd;
- struct fs·Entry *it;
-
- flags = 0;
- if(fs->flags & fs·nolinks)
- flags |= AT_SYMLINK_NOFOLLOW;
-
- /* get info for base relative to current fd */
- if(fstatat(fs->fd, fs->base, &cwd, flags) < 0){
- if(fs->flags & fs·verbose)
- errorf("stat: %s", fs->path);
- return;
- }
-
- /* if we hit a file, finish! */
- if(!S_ISDIR(cwd.st_mode)) {
- fs->func(fs->data, fs->base, fs->path, &cwd);
- return;
- }
-
- /* 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);
- if (!new)
- return;
- }
-
- /*
- * operate on directory first if preorder traversal
- * truncate recursion if callback returns an error code
- */
- if (fs->flags & fs·preorder) {
- if (fs->func(fs->data, fs->base, fs->path, &cwd))
- return;
- }
-
- /* open directory */
- if(!fs->max || fs->lev + 1 < fs->max) {
- fd = openat(fs->fd, fs->base, O_RDONLY | O_CLOEXEC | O_DIRECTORY);
- if (fd < 0)
- errorf("open %s:", fs->path);
-
- if (!(dir=fdopendir(fd))) {
- if(fs->flags & fs·verbose)
- errorf("fdopendir: %s", fs->path);
- return;
- }
-
- ofd = fs->fd, fs->fd = fd;
-
- /* traverse children */
- e = fs->end, b = fs->base;
- if (fs->end[-1] != '/')
- *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;
-
- fs->end = str·copyn(fs->base, d->d_name, arrend(fs->path) - fs->base);
-
- fs->lev++;
- fs·walk(fs);
- fs->lev--;
- }
- *e = 0;
- fs->fd = ofd;
- fs->end = e, fs->base = b;
- closedir(dir);
- }
-
- /* operate on directory if postorder (default) traversal */
- if (!(fs->flags & fs·preorder))
- fs->func(fs->data, fs->base, fs->path, &cwd);
-
- if (!fs->lev)
- forget(fs->hist);
-}