From 40df4d3d4d6389fbec579e555e79e0ca577e342a Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Mon, 21 Nov 2016 15:25:44 -0500 Subject: bftw: Make bftw_flags more similar to fts() options. --- bftw.c | 14 +++++++++----- bftw.h | 16 +++++++--------- eval.c | 7 +++++-- parse.c | 18 +++++++++--------- 4 files changed, 30 insertions(+), 25 deletions(-) diff --git a/bftw.c b/bftw.c index e2bfcc6..ea683be 100644 --- a/bftw.c +++ b/bftw.c @@ -785,18 +785,22 @@ static void bftw_init_buffers(struct bftw_state *state, const struct dirent *de) ftwbuf->typeflag = BFTW_DIR; } - bool follow = state->flags & (current ? BFTW_FOLLOW_NONROOT : BFTW_FOLLOW_ROOT); + int follow_flags = BFTW_LOGICAL; + if (ftwbuf->depth == 0) { + follow_flags |= BFTW_COMFOLLOW; + } + bool follow = state->flags & follow_flags; ftwbuf->at_flags = follow ? 0 : AT_SYMLINK_NOFOLLOW; bool detect_cycles = (state->flags & BFTW_DETECT_CYCLES) && state->status == BFTW_CHILD; - bool mount = state->flags & BFTW_MOUNT; + bool xdev = state->flags & BFTW_XDEV; if ((state->flags & BFTW_STAT) || ftwbuf->typeflag == BFTW_UNKNOWN || (ftwbuf->typeflag == BFTW_LNK && follow) - || (ftwbuf->typeflag == BFTW_DIR && (detect_cycles || mount))) { + || (ftwbuf->typeflag == BFTW_DIR && (detect_cycles || xdev))) { int ret = ftwbuf_stat(ftwbuf, &state->statbuf, ftwbuf->at_flags); if (ret != 0 && follow && errno == ENOENT) { // Could be a broken symlink, retry without following @@ -857,7 +861,7 @@ static struct dircache_entry *bftw_add(struct bftw_state *state, const char *nam return NULL; } - if (state->flags & (BFTW_DETECT_CYCLES | BFTW_MOUNT)) { + if (state->flags & (BFTW_DETECT_CYCLES | BFTW_XDEV)) { const struct stat *statbuf = state->ftwbuf.statbuf; if (statbuf) { entry->dev = statbuf->st_dev; @@ -1043,7 +1047,7 @@ int bftw(const char *path, bftw_fn *fn, int nopenfd, enum bftw_flags flags, void if (state.ftwbuf.typeflag == BFTW_DIR) { const struct stat *statbuf = state.ftwbuf.statbuf; - if ((flags & BFTW_MOUNT) + if ((flags & BFTW_XDEV) && statbuf && statbuf->st_dev != state.current->dev) { continue; diff --git a/bftw.h b/bftw.h index 31498f7..7bfb5fb 100644 --- a/bftw.h +++ b/bftw.h @@ -113,21 +113,19 @@ typedef enum bftw_action bftw_fn(struct BFTW *ftwbuf, void *ptr); */ enum bftw_flags { /** stat() each encountered file. */ - BFTW_STAT = 1 << 0, + BFTW_STAT = 1 << 0, /** Attempt to recover from encountered errors. */ - BFTW_RECOVER = 1 << 1, + BFTW_RECOVER = 1 << 1, /** Visit directories in post-order as well as pre-order. */ - BFTW_DEPTH = 1 << 2, + BFTW_DEPTH = 1 << 2, /** If the initial path is a symbolic link, follow it. */ - BFTW_FOLLOW_ROOT = 1 << 3, - /** Follow non-root symbolic links. */ - BFTW_FOLLOW_NONROOT = 1 << 4, + BFTW_COMFOLLOW = 1 << 3, /** Follow all symbolic links. */ - BFTW_FOLLOW = BFTW_FOLLOW_ROOT | BFTW_FOLLOW_NONROOT, + BFTW_LOGICAL = 1 << 4, /** Detect directory cycles. */ - BFTW_DETECT_CYCLES = 1 << 5, + BFTW_DETECT_CYCLES = 1 << 5, /** Stay on the same filesystem. */ - BFTW_MOUNT = 1 << 6, + BFTW_XDEV = 1 << 6, }; /** diff --git a/eval.c b/eval.c index 4fc91cc..9dcb854 100644 --- a/eval.c +++ b/eval.c @@ -803,8 +803,11 @@ bool eval_type(const struct expr *expr, struct eval_state *state) { bool eval_xtype(const struct expr *expr, struct eval_state *state) { struct BFTW *ftwbuf = state->ftwbuf; - bool is_root = ftwbuf->depth == 0; - bool follow = state->cmdline->flags & (is_root ? BFTW_FOLLOW_ROOT : BFTW_FOLLOW_NONROOT); + int follow_flags = BFTW_LOGICAL; + if (ftwbuf->depth == 0) { + follow_flags |= BFTW_COMFOLLOW; + } + bool follow = state->cmdline->flags & follow_flags; bool is_link = ftwbuf->typeflag == BFTW_LNK; if (follow == is_link) { diff --git a/parse.c b/parse.c index a85390a..bf3a09a 100644 --- a/parse.c +++ b/parse.c @@ -271,7 +271,7 @@ static void debug_opt(const struct parser_state *state, const char *format, ...) static int stat_arg(const struct parser_state *state, struct expr *expr, struct stat *sb) { const struct cmdline *cmdline = state->cmdline; - bool follow = cmdline->flags & BFTW_FOLLOW; + bool follow = cmdline->flags & (BFTW_COMFOLLOW | BFTW_LOGICAL); int flags = follow ? 0 : AT_SYMLINK_NOFOLLOW; int ret = fstatat(AT_FDCWD, expr->sdata, sb, flags); @@ -684,7 +684,7 @@ static struct expr *parse_optlevel(struct parser_state *state, int arg1, int arg */ static struct expr *parse_follow(struct parser_state *state, int flags, int option) { struct cmdline *cmdline = state->cmdline; - cmdline->flags &= ~(BFTW_FOLLOW | BFTW_DETECT_CYCLES); + cmdline->flags &= ~(BFTW_COMFOLLOW | BFTW_LOGICAL | BFTW_DETECT_CYCLES); cmdline->flags |= flags; if (option) { return parse_nullary_positional_option(state); @@ -1069,7 +1069,7 @@ static struct expr *parse_links(struct parser_state *state, int arg1, int arg2) * Parse -mount, -xdev. */ static struct expr *parse_mount(struct parser_state *state, int arg1, int arg2) { - state->cmdline->flags |= BFTW_MOUNT; + state->cmdline->flags |= BFTW_XDEV; return parse_nullary_option(state); } @@ -1677,8 +1677,8 @@ static const struct table_entry parse_table[] = { {"D", false, parse_debug}, {"O", true, parse_optlevel}, {"P", false, parse_follow, 0, false}, - {"H", false, parse_follow, BFTW_FOLLOW_ROOT, false}, - {"L", false, parse_follow, BFTW_FOLLOW | BFTW_DETECT_CYCLES, false}, + {"H", false, parse_follow, BFTW_COMFOLLOW, false}, + {"L", false, parse_follow, BFTW_LOGICAL | BFTW_DETECT_CYCLES, false}, {"a"}, {"amin", false, parse_acmtime, ATIME, MINUTES}, {"and"}, @@ -1698,7 +1698,7 @@ static const struct table_entry parse_table[] = { {"executable", false, parse_access, X_OK}, {"f", false, parse_f}, {"false", false, parse_const, false}, - {"follow", false, parse_follow, BFTW_FOLLOW | BFTW_DETECT_CYCLES, true}, + {"follow", false, parse_follow, BFTW_LOGICAL | BFTW_DETECT_CYCLES, true}, {"fprint", false, parse_fprint}, {"fprint0", false, parse_fprint0}, {"gid", false, parse_gid}, @@ -2164,9 +2164,9 @@ static struct expr *optimize_whole_expr(const struct parser_state *state, struct * Dump the parsed form of the command line, for debugging. */ void dump_cmdline(const struct cmdline *cmdline, bool verbose) { - if (cmdline->flags & BFTW_FOLLOW_NONROOT) { + if (cmdline->flags & BFTW_LOGICAL) { fputs("-L ", stderr); - } else if (cmdline->flags & BFTW_FOLLOW_ROOT) { + } else if (cmdline->flags & BFTW_COMFOLLOW) { fputs("-H ", stderr); } else { fputs("-P ", stderr); @@ -2208,7 +2208,7 @@ void dump_cmdline(const struct cmdline *cmdline, bool verbose) { if (cmdline->ignore_races) { fputs("-ignore_readdir_race ", stderr); } - if (cmdline->flags & BFTW_MOUNT) { + if (cmdline->flags & BFTW_XDEV) { fputs("-mount ", stderr); } if (cmdline->mindepth != 0) { -- cgit v1.2.3