Set DIRTREE_SYMFOLLOW when we followed a symlink to this node.

(Mask out the bit in callers that just want DIRTREE_COMEAGAIN.)
This commit is contained in:
Rob Landley 2023-10-01 03:21:20 -05:00
parent e606e0f906
commit 97d03ecf95
5 changed files with 9 additions and 8 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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--;

View File

@ -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) {