From c09c83d321417576eb6c7c3f6222e2ed05110c1c Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Sun, 14 Feb 2016 13:01:17 -0500 Subject: Implement -mount/-xdev. --- bftw.c | 13 +++++++++++-- bftw.h | 2 ++ parse.c | 8 +++++++- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/bftw.c b/bftw.c index e64a93c..edca612 100644 --- a/bftw.c +++ b/bftw.c @@ -656,10 +656,12 @@ static void bftw_init_buffers(struct bftw_state *state, const struct dirent *de) bool detect_cycles = (state->flags & BFTW_DETECT_CYCLES) && state->status == BFTW_CHILD; + bool mount = state->flags & BFTW_MOUNT; + if ((state->flags & BFTW_STAT) || ftwbuf->typeflag == BFTW_UNKNOWN || (ftwbuf->typeflag == BFTW_LNK && follow) - || (ftwbuf->typeflag == BFTW_DIR && detect_cycles)) { + || (ftwbuf->typeflag == BFTW_DIR && (detect_cycles || mount))) { int ret = ftwbuf_stat(ftwbuf, &state->statbuf, ftwbuf->at_flags); if (ret != 0 && follow && errno == ENOENT) { // Could be a broken symlink, retry without following @@ -719,7 +721,7 @@ static struct dircache_entry *bftw_add(struct bftw_state *state, const char *nam return NULL; } - if (state->flags & BFTW_DETECT_CYCLES) { + if (state->flags & (BFTW_DETECT_CYCLES | BFTW_MOUNT)) { const struct stat *statbuf = state->ftwbuf.statbuf; if (statbuf) { entry->dev = statbuf->st_dev; @@ -910,6 +912,13 @@ 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) + && statbuf + && statbuf->st_dev != state.current->dev) { + continue; + } + if (bftw_push(&state, de->d_name) != 0) { goto fail; } diff --git a/bftw.h b/bftw.h index 790d422..0b692b0 100644 --- a/bftw.h +++ b/bftw.h @@ -120,6 +120,8 @@ enum bftw_flags { BFTW_FOLLOW = BFTW_FOLLOW_ROOT | BFTW_FOLLOW_NONROOT, /** Detect directory cycles. */ BFTW_DETECT_CYCLES = 1 << 5, + /** Stay on the same filesystem. */ + BFTW_MOUNT = 1 << 6, }; /** diff --git a/parse.c b/parse.c index 6177e76..74b51cb 100644 --- a/parse.c +++ b/parse.c @@ -679,6 +679,9 @@ static struct expr *parse_literal(struct parser_state *state) { return parse_depth(state, arg, &state->cmdline->maxdepth); } else if (strcmp(arg, "-mmin") == 0) { return parse_acmtime(state, arg, MTIME, MINUTES); + } else if (strcmp(arg, "-mount") == 0) { + state->cmdline->flags |= BFTW_MOUNT; + return new_option(state, arg); } else if (strcmp(arg, "-mtime") == 0) { return parse_acmtime(state, arg, MTIME, DAYS); } @@ -762,7 +765,10 @@ static struct expr *parse_literal(struct parser_state *state) { break; case 'x': - if (strcmp(arg, "-xtype") == 0) { + if (strcmp(arg, "-xdev") == 0) { + state->cmdline->flags |= BFTW_MOUNT; + return new_option(state, arg); + } else if (strcmp(arg, "-xtype") == 0) { return parse_type(state, arg, eval_xtype); } break; -- cgit v1.2.3