From bb77dde5ddfba8fe0c819b18b547c2d710956502 Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Thu, 21 Apr 2016 17:46:25 -0500 Subject: Have dirtree_recurse() take the new dirfd as an argument. --- lib/dirtree.c | 12 +++++------- lib/lib.h | 2 +- toys/posix/ls.c | 4 ++-- 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 -- cgit v1.2.3