aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/dirtree.c12
-rw-r--r--lib/lib.h2
-rw-r--r--toys/posix/ls.c4
3 files changed, 8 insertions, 10 deletions
diff --git a/lib/dirtree.c b/lib/dirtree.c
index cc1ab90c..8f235ed4 100644
--- a/lib/dirtree.c
+++ b/lib/dirtree.c
@@ -110,12 +110,9 @@ struct dirtree *dirtree_handle_callback(struct dirtree *new,
if (!callback) return new;
flags = callback(new);
- if (S_ISDIR(new->st.st_mode)) {
- if (flags & (DIRTREE_RECURSE|DIRTREE_COMEAGAIN)) {
- new->dirfd = openat(dirtree_parentfd(new), new->name, O_CLOEXEC);
- flags = dirtree_recurse(new, callback, flags);
- }
- }
+ if (S_ISDIR(new->st.st_mode) && (flags & (DIRTREE_RECURSE|DIRTREE_COMEAGAIN)))
+ flags = dirtree_recurse(new, callback,
+ openat(dirtree_parentfd(new), new->name, O_CLOEXEC), flags);
// If this had children, it was callback's job to free them already.
if (!(flags & DIRTREE_SAVE)) {
@@ -130,12 +127,13 @@ struct dirtree *dirtree_handle_callback(struct dirtree *new,
// callback(). Uses and closes supplied ->dirfd.
int dirtree_recurse(struct dirtree *node,
- int (*callback)(struct dirtree *node), int flags)
+ int (*callback)(struct dirtree *node), int dirfd, int flags)
{
struct dirtree *new, **ddt = &(node->child);
struct dirent *entry;
DIR *dir;
+ node->dirfd = dirfd;
if (node->dirfd == -1 || !(dir = fdopendir(node->dirfd))) {
if (!(flags & DIRTREE_SHUTUP)) {
char *path = dirtree_path(node, 0);
diff --git a/lib/lib.h b/lib/lib.h
index 23a3b2b3..aafa9693 100644
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -84,7 +84,7 @@ char *dirtree_path(struct dirtree *node, int *plen);
int dirtree_notdotdot(struct dirtree *catch);
int dirtree_parentfd(struct dirtree *node);
int dirtree_recurse(struct dirtree *node, int (*callback)(struct dirtree *node),
- int symfollow);
+ int dirfd, int symfollow);
struct dirtree *dirtree_flagread(char *path, int flags,
int (*callback)(struct dirtree *node));
struct dirtree *dirtree_read(char *path, int (*callback)(struct dirtree *node));
diff --git a/toys/posix/ls.c b/toys/posix/ls.c
index bec76e99..2ebc062a 100644
--- a/toys/posix/ls.c
+++ b/toys/posix/ls.c
@@ -337,8 +337,8 @@ static void listfiles(int dirfd, struct dirtree *indir)
} else {
// Read directory contents. We dup() the fd because this will close it.
// This reads/saves contents to display later, except for in "ls -1f" mode.
- indir->dirfd = dup(dirfd);
- dirtree_recurse(indir, filter, DIRTREE_SYMFOLLOW*!!(flags&FLAG_L));
+ dirtree_recurse(indir, filter, dup(dirfd),
+ DIRTREE_SYMFOLLOW*!!(flags&FLAG_L));
}
// Copy linked list to array and sort it. Directories go in array because