summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2016-02-14 13:01:17 -0500
committerTavian Barnes <tavianator@tavianator.com>2016-02-14 13:01:17 -0500
commitc09c83d321417576eb6c7c3f6222e2ed05110c1c (patch)
tree15c37aecc5de5cf9311a86750d31a5804a2f2ef7
parent4fdc29a88b9923d874375c72774a01a91a7fc253 (diff)
downloadbfs-c09c83d321417576eb6c7c3f6222e2ed05110c1c.tar.xz
Implement -mount/-xdev.
-rw-r--r--bftw.c13
-rw-r--r--bftw.h2
-rw-r--r--parse.c8
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;