diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2025-04-01 06:50:26 -0400 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2025-04-01 07:28:02 -0400 |
commit | a662fda2642e17478bc8e78adb4c6642a8505cdb (patch) | |
tree | 95107aed722b822a72856f75bd2746b0318885b8 /src/parse.c | |
parent | b1fe97289315cfb6278eec4554b92776df98f28d (diff) | |
download | bfs-a662fda2642e17478bc8e78adb4c6642a8505cdb.tar.xz |
parse: Only process the last -files0-from
GNU find intentionally makes later -files0-from options override earlier
ones, for symmetry with similar features like du --files0-from. Change
bfs to match.
Link: https://savannah.gnu.org/bugs/?66965
Diffstat (limited to 'src/parse.c')
-rw-r--r-- | src/parse.c | 122 |
1 files changed, 68 insertions, 54 deletions
diff --git a/src/parse.c b/src/parse.c index 9631b91..a19e689 100644 --- a/src/parse.c +++ b/src/parse.c @@ -84,8 +84,6 @@ struct bfs_parser { enum use_color use_color; /** Whether a -print action is implied. */ bool implicit_print; - /** Whether the default root "." should be used. */ - bool implicit_root; /** Whether the expression has started. */ bool expr_started; /** Whether an information option like -help or -version was passed. */ @@ -105,6 +103,8 @@ struct bfs_parser { const struct bfs_expr *mount_expr; /** An "-xdev" expression, if any. */ const struct bfs_expr *xdev_expr; + /** A "-files0-from" expression, if any. */ + const struct bfs_expr *files0_expr; /** An expression that consumes stdin, if any. */ const struct bfs_expr *stdin_expr; @@ -427,7 +427,6 @@ static int parse_root(struct bfs_parser *parser, const char *path) { return -1; } - parser->implicit_root = false; return 0; } @@ -1351,51 +1350,14 @@ static struct bfs_expr *parse_files0_from(struct bfs_parser *parser, int arg1, i return NULL; } - const char *from = expr->argv[1]; - - FILE *file; - if (strcmp(from, "-") == 0) { - if (!consume_stdin(parser, expr)) { - return NULL; - } - file = stdin; - } else { - file = xfopen(from, O_RDONLY | O_CLOEXEC); - } - if (!file) { - parse_expr_error(parser, expr, "%s.\n", errstr()); - return NULL; - } - - while (true) { - char *path = xgetdelim(file, '\0'); - if (!path) { - if (errno) { - goto fail; - } else { - break; - } - } - - int ret = parse_root(parser, path); - free(path); - if (ret != 0) { - goto fail; - } - } - - if (file != stdin) { - fclose(file); - } - - parser->implicit_root = false; + // For compatibility with GNU find, + // + // bfs -files0-from a -files0-from b + // + // should *only* use b, not a. So stash the expression here and only + // process the last one at the end of parsing. + parser->files0_expr = expr; return expr; - -fail: - if (file != stdin) { - fclose(file); - } - return NULL; } /** @@ -3546,6 +3508,55 @@ static struct bfs_expr *parse_expr(struct bfs_parser *parser) { return expr; } +/** Handle -files0-from after parsing. */ +static int parse_files0_roots(struct bfs_parser *parser) { + const struct bfs_expr *expr = parser->files0_expr; + const char *from = expr->argv[1]; + + FILE *file; + if (strcmp(from, "-") == 0) { + if (!consume_stdin(parser, expr)) { + return -1; + } + file = stdin; + } else { + file = xfopen(from, O_RDONLY | O_CLOEXEC); + } + if (!file) { + parse_expr_error(parser, expr, "%s.\n", errstr()); + return -1; + } + + while (true) { + char *path = xgetdelim(file, '\0'); + if (!path) { + if (errno) { + goto fail; + } else { + break; + } + } + + int ret = parse_root(parser, path); + free(path); + if (ret != 0) { + goto fail; + } + } + + if (file != stdin) { + fclose(file); + } + + return 0; + +fail: + if (file != stdin) { + fclose(file); + } + return -1; +} + /** * Parse the top-level expression. */ @@ -3571,6 +3582,16 @@ static struct bfs_expr *parse_whole_expr(struct bfs_parser *parser) { return NULL; } + if (parser->files0_expr) { + if (parse_files0_roots(parser) != 0) { + return NULL; + } + } else if (ctx->npaths == 0) { + if (parse_root(parser, ".") != 0) { + return NULL; + } + } + if (parser->implicit_print) { const struct bfs_expr *limit = parser->limit_expr; if (limit) { @@ -3842,7 +3863,6 @@ struct bfs_ctx *bfs_parse_cmdline(int argc, char *argv[]) { .stdout_tty = stdout_tty, .use_color = use_color, .implicit_print = true, - .implicit_root = true, .just_info = false, .excluding = false, .last_arg = NULL, @@ -3879,12 +3899,6 @@ struct bfs_ctx *bfs_parse_cmdline(int argc, char *argv[]) { goto fail; } - if (ctx->npaths == 0 && parser.implicit_root) { - if (parse_root(&parser, ".") != 0) { - goto fail; - } - } - if ((ctx->flags & BFTW_FOLLOW_ALL) && !ctx->unique) { // We need bftw() to detect cycles unless -unique does it for us ctx->flags |= BFTW_DETECT_CYCLES; |