From 97d03ecf95957fefc5bb9fdb5110e71f1000a4de Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Sun, 1 Oct 2023 03:21:20 -0500 Subject: [PATCH] Set DIRTREE_SYMFOLLOW when we followed a symlink to this node. (Mask out the bit in callers that just want DIRTREE_COMEAGAIN.) --- lib/dirtree.c | 2 ++ toys/posix/chgrp.c | 2 +- toys/posix/cp.c | 2 +- toys/posix/du.c | 6 +++--- toys/posix/find.c | 5 ++--- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/dirtree.c b/lib/dirtree.c index 00de64e4..2d120890 100644 --- a/lib/dirtree.c +++ b/lib/dirtree.c @@ -182,6 +182,8 @@ int dirtree_recurse(struct dirtree *node, if ((flags&DIRTREE_PROC) && !isdigit(*entry->d_name)) continue; if ((flags&DIRTREE_BREADTH) && isdotdot(entry->d_name)) continue; if (!(new = dirtree_add_node(node, entry->d_name, flags))) continue; + if ((flags&DIRTREE_SYMFOLLOW) && entry->d_type==DT_LNK + && !S_ISLNK(new->st.st_mode)) new->again |= DIRTREE_SYMFOLLOW; if (!new->st.st_blksize && !new->st.st_mode) new->st.st_mode = entry->d_type<<12; new = dirtree_handle_callback(new, callback); diff --git a/toys/posix/chgrp.c b/toys/posix/chgrp.c index 73c4b223..a4fc41c0 100644 --- a/toys/posix/chgrp.c +++ b/toys/posix/chgrp.c @@ -48,7 +48,7 @@ static int do_chgrp(struct dirtree *node) // Depth first search if (!dirtree_notdotdot(node)) return 0; - if (FLAG(R) && !node->again && S_ISDIR(node->st.st_mode)) + if (FLAG(R) && !(node->again&DIRTREE_COMEAGAIN) && S_ISDIR(node->st.st_mode)) return DIRTREE_COMEAGAIN|DIRTREE_SYMFOLLOW*FLAG(L); fd = dirtree_parentfd(node); diff --git a/toys/posix/cp.c b/toys/posix/cp.c index c2b838ed..37c2afd0 100644 --- a/toys/posix/cp.c +++ b/toys/posix/cp.c @@ -161,7 +161,7 @@ static int cp_node(struct dirtree *try) if (!dirtree_notdotdot(try)) return 0; // If returning from COMEAGAIN, jump straight to -p logic at end. - if (S_ISDIR(try->st.st_mode) && try->again) { + if (S_ISDIR(try->st.st_mode) && (try->again&DIRTREE_COMEAGAIN)) { fdout = try->extra; err = 0; diff --git a/toys/posix/du.c b/toys/posix/du.c index 8bf9575d..2e660063 100644 --- a/toys/posix/du.c +++ b/toys/posix/du.c @@ -108,7 +108,7 @@ static int seen_inode(void **list, struct stat *st) // dirtree callback, compute/display size of node static int do_du(struct dirtree *node) { - unsigned long blocks; + unsigned long blocks, again = node->again&DIRTREE_COMEAGAIN; if (!node->parent) TT.st_dev = node->st.st_dev; else if (!dirtree_notdotdot(node)) return 0; @@ -124,12 +124,12 @@ static int do_du(struct dirtree *node) } // Don't count hard links twice - if (!FLAG(l) && !node->again) + if (!FLAG(l) && !again) if (seen_inode(&TT.inodes, &node->st)) return 0; // Collect child info before printing directory size if (S_ISDIR(node->st.st_mode)) { - if (!node->again) { + if (!again) { TT.depth++; return DIRTREE_COMEAGAIN|DIRTREE_SYMFOLLOW*FLAG(L); } else TT.depth--; diff --git a/toys/posix/find.c b/toys/posix/find.c index 8beb521e..0fde9c9e 100644 --- a/toys/posix/find.c +++ b/toys/posix/find.c @@ -215,8 +215,7 @@ static int do_find(struct dirtree *new) struct double_list *argdata = TT.argdata; char *s, **ss, *arg; - recurse = DIRTREE_STATLESS|DIRTREE_COMEAGAIN| - (DIRTREE_SYMFOLLOW*!!(toys.optflags&FLAG_L)); + recurse = DIRTREE_STATLESS|DIRTREE_COMEAGAIN|DIRTREE_SYMFOLLOW*FLAG(L); // skip . and .. below topdir, handle -xdev and -depth if (new) { @@ -235,7 +234,7 @@ static int do_find(struct dirtree *new) if (S_ISDIR(new->st.st_mode)) { // Descending into new directory - if (!new->again) { + if (!(new->again&DIRTREE_COMEAGAIN)) { struct dirtree *n; for (n = new->parent; n; n = n->parent) { -- 2.39.2