aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/dirtree.c25
-rw-r--r--lib/lib.h2
-rw-r--r--toys/chgrp.c4
3 files changed, 15 insertions, 16 deletions
diff --git a/lib/dirtree.c b/lib/dirtree.c
index 01e0ea8c..291f99a4 100644
--- a/lib/dirtree.c
+++ b/lib/dirtree.c
@@ -78,21 +78,20 @@ int dirtree_notdotdot(struct dirtree *catch)
return DIRTREE_SAVE|DIRTREE_RECURSE;
}
-// depth first recursion
-int dirtree_comeagain(struct dirtree *try, int recurse)
+// get open filehandle for node in extra, giving caller the option of
+// using DIRTREE_COMEAGAIN or not.
+int dirtree_opennode(struct dirtree *try)
{
- int ret = dirtree_notdotdot(try);
- if (ret) {
- if (S_ISDIR(try->st.st_mode)) {
- if (!try->extra) {
- try->extra = xdup(try->data);
- if (recurse) return DIRTREE_COMEAGAIN;
- }
- } else try->extra = openat(try->parent ? try->parent->data : AT_FDCWD,
- try->name, 0);
- }
+ if (!dirtree_notdotdot(try)) return 0;
+ if (S_ISDIR(try->st.st_mode)) {
+ if (!try->extra) {
+ try->extra = xdup(try->data);
+ return DIRTREE_COMEAGAIN;
+ }
+ } else try->extra = openat(try->parent ? try->parent->data : AT_FDCWD,
+ try->name, 0);
- return ret;
+ return DIRTREE_SAVE|DIRTREE_RECURSE;
}
// Handle callback for a node in the tree. Returns saved node(s) or NULL.
diff --git a/lib/lib.h b/lib/lib.h
index 88810b1f..b45ea753 100644
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -74,7 +74,7 @@ struct dirtree {
struct dirtree *dirtree_add_node(int dirfd, char *name);
char *dirtree_path(struct dirtree *node, int *plen);
int dirtree_notdotdot(struct dirtree *catch);
-int dirtree_comeagain(struct dirtree *try, int recurse);
+int dirtree_opennode(struct dirtree *try);
struct dirtree *handle_callback(struct dirtree *new,
int (*callback)(struct dirtree *node));
void dirtree_recurse(struct dirtree *node,
diff --git a/toys/chgrp.c b/toys/chgrp.c
index 935e1781..521db0b7 100644
--- a/toys/chgrp.c
+++ b/toys/chgrp.c
@@ -42,8 +42,8 @@ static int do_chgrp(struct dirtree *node)
{
int ret, flags = toys.optflags;
- ret = dirtree_comeagain(node, flags & FLAG_R);
- if (!ret || ret == DIRTREE_COMEAGAIN) return ret;
+ ret = dirtree_opennode(node);
+ if (!ret || ((flags & FLAG_R) && ret == DIRTREE_COMEAGAIN)) return ret;
if (node->extra != -1) ret = fchown(node->extra, -1, TT.group);