From 7fc960a23eab7fce9f5e0666b1a9b3f5eae832af Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Tue, 12 Feb 2019 17:36:31 -0500 Subject: bftw: Switch from taking separate parameters to a parameters struct --- bftw.c | 26 +++++++++++++------------- bftw.h | 30 +++++++++++++++++++----------- eval.c | 24 ++++++++++++++++++------ 3 files changed, 50 insertions(+), 30 deletions(-) diff --git a/bftw.c b/bftw.c index 118a441..6795bd0 100644 --- a/bftw.c +++ b/bftw.c @@ -764,11 +764,11 @@ static int bftw_stat(struct BFTW *ftwbuf, struct bfs_stat *sb) { */ struct bftw_state { /** bftw() callback. */ - bftw_fn *fn; - /** bftw() flags. */ - int flags; + bftw_callback *callback; /** bftw() callback data. */ void *ptr; + /** bftw() flags. */ + enum bftw_flags flags; /** The appropriate errno value, if any. */ int error; @@ -795,21 +795,21 @@ struct bftw_state { /** * Initialize the bftw() state. */ -static int bftw_state_init(struct bftw_state *state, const char *root, bftw_fn *fn, int nopenfd, int flags, void *ptr) { +static int bftw_state_init(struct bftw_state *state, const char *root, const struct bftw_args *args) { state->root = root; - state->fn = fn; - state->flags = flags; - state->ptr = ptr; + state->callback = args->callback; + state->ptr = args->ptr; + state->flags = args->flags; state->error = 0; - if (nopenfd < 2) { + if (args->nopenfd < 2) { errno = EMFILE; goto err; } // -1 to account for dup() - if (bftw_cache_init(&state->cache, nopenfd - 1) != 0) { + if (bftw_cache_init(&state->cache, args->nopenfd - 1) != 0) { goto err; } @@ -972,7 +972,7 @@ static enum bftw_action bftw_visit_path(struct bftw_state *state) { // Defensive copy struct BFTW ftwbuf = state->ftwbuf; - enum bftw_action action = state->fn(&ftwbuf, state->ptr); + enum bftw_action action = state->callback(&ftwbuf, state->ptr); switch (action) { case BFTW_CONTINUE: case BFTW_SKIP_SIBLINGS: @@ -1113,9 +1113,9 @@ static int bftw_state_destroy(struct bftw_state *state) { } } -int bftw(const char *path, bftw_fn *fn, int nopenfd, enum bftw_flags flags, void *ptr) { +int bftw(const char *path, const struct bftw_args *args) { struct bftw_state state; - if (bftw_state_init(&state, path, fn, nopenfd, flags, ptr) != 0) { + if (bftw_state_init(&state, path, args) != 0) { return -1; } @@ -1163,7 +1163,7 @@ int bftw(const char *path, bftw_fn *fn, int nopenfd, enum bftw_flags flags, void if (state.ftwbuf.typeflag == BFTW_DIR) { const struct bfs_stat *statbuf = state.ftwbuf.statbuf; - if ((flags & BFTW_XDEV) + if ((args->flags & BFTW_XDEV) && statbuf && statbuf->dev != reader->dir->dev) { goto read; diff --git a/bftw.h b/bftw.h index bed5800..6d1850f 100644 --- a/bftw.h +++ b/bftw.h @@ -1,6 +1,6 @@ /**************************************************************************** * bfs * - * Copyright (C) 2015-2018 Tavian Barnes * + * Copyright (C) 2015-2019 Tavian Barnes * * * * Permission to use, copy, modify, and/or distribute this software for any * * purpose with or without fee is hereby granted. * @@ -125,7 +125,7 @@ enum bftw_action { * @return * An action value. */ -typedef enum bftw_action bftw_fn(struct BFTW *ftwbuf, void *ptr); +typedef enum bftw_action bftw_callback(struct BFTW *ftwbuf, void *ptr); /** * Flags that control bftw() behavior. @@ -147,6 +147,20 @@ enum bftw_flags { BFTW_XDEV = 1 << 6, }; +/** + * Structure for holding the arguments passed to bftw(). + */ +struct bftw_args { + /** The callback to invoke. */ + bftw_callback *callback; + /** A pointer which is passed to the callback. */ + void *ptr; + /** The maximum number of file descriptors to keep open. */ + int nopenfd; + /** Flags that control bftw() behaviour. */ + enum bftw_flags flags; +}; + /** * Breadth First Tree Walk (or Better File Tree Walk). * @@ -156,17 +170,11 @@ enum bftw_flags { * * @param path * The starting path. - * @param fn - * The callback to invoke. - * @param nopenfd - * The maximum number of file descriptors to keep open. - * @param flags - * Flags that control bftw() behavior. - * @param ptr - * A generic pointer which is passed to fn(). + * @param args + * The arguments that control the walk. * @return * 0 on success, or -1 on failure. */ -int bftw(const char *path, bftw_fn *fn, int nopenfd, enum bftw_flags flags, void *ptr); +int bftw(const char *path, const struct bftw_args *args); #endif // BFS_BFTW_H diff --git a/eval.c b/eval.c index 53eacf8..028b31d 100644 --- a/eval.c +++ b/eval.c @@ -1383,8 +1383,6 @@ int eval_cmdline(const struct cmdline *cmdline) { return EXIT_SUCCESS; } - int nopenfd = infer_fdlimit(cmdline); - struct callback_args args = { .cmdline = cmdline, .ret = EXIT_SUCCESS, @@ -1397,14 +1395,28 @@ int eval_cmdline(const struct cmdline *cmdline) { args.seen = &seen; } + struct bftw_args bftw_args = { + .callback = cmdline_callback, + .ptr = &args, + .nopenfd = infer_fdlimit(cmdline), + .flags = cmdline->flags, + }; + for (struct root *root = cmdline->roots; root && !args.quit; root = root->next) { if (cmdline->debug & DEBUG_SEARCH) { - fprintf(stderr, "bftw(\"%s\", cmdline_callback, %d, ", root->path, nopenfd); - dump_bftw_flags(cmdline->flags); - fprintf(stderr, ", &args)\n"); + fprintf(stderr, + "bftw(\"%s\", { " + ".callback = cmdline_callback, " + ".ptr = &args, " + ".nopenfd = %d, " + ".flags = ", + root->path, + bftw_args.nopenfd); + dump_bftw_flags(bftw_args.flags); + fprintf(stderr, " })\n"); } - if (bftw(root->path, cmdline_callback, nopenfd, cmdline->flags, &args) != 0) { + if (bftw(root->path, &bftw_args) != 0) { args.ret = EXIT_FAILURE; perror("bftw()"); } -- cgit v1.2.3