summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bftw.c14
-rw-r--r--bftw.h16
-rw-r--r--eval.c7
-rw-r--r--parse.c18
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) {