diff options
Diffstat (limited to 'ctx.c')
-rw-r--r-- | ctx.c | 284 |
1 files changed, 0 insertions, 284 deletions
@@ -1,284 +0,0 @@ -/**************************************************************************** - * bfs * - * Copyright (C) 2015-2021 Tavian Barnes <tavianator@tavianator.com> * - * * - * Permission to use, copy, modify, and/or distribute this software for any * - * purpose with or without fee is hereby granted. * - * * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - ****************************************************************************/ - -#include "ctx.h" -#include "color.h" -#include "darray.h" -#include "diag.h" -#include "expr.h" -#include "mtab.h" -#include "pwcache.h" -#include "stat.h" -#include "trie.h" -#include <assert.h> -#include <errno.h> -#include <limits.h> -#include <stdio.h> -#include <stdlib.h> - -const char *debug_flag_name(enum debug_flags flag) { - switch (flag) { - case DEBUG_COST: - return "cost"; - case DEBUG_EXEC: - return "exec"; - case DEBUG_OPT: - return "opt"; - case DEBUG_RATES: - return "rates"; - case DEBUG_SEARCH: - return "search"; - case DEBUG_STAT: - return "stat"; - case DEBUG_TREE: - return "tree"; - - case DEBUG_ALL: - break; - } - - assert(!"Unrecognized debug flag"); - return "???"; -} - -struct bfs_ctx *bfs_ctx_new(void) { - struct bfs_ctx *ctx = malloc(sizeof(*ctx)); - if (!ctx) { - return NULL; - } - - ctx->argv = NULL; - ctx->paths = NULL; - ctx->expr = NULL; - ctx->exclude = NULL; - - ctx->mindepth = 0; - ctx->maxdepth = INT_MAX; - ctx->flags = BFTW_RECOVER; - ctx->strategy = BFTW_BFS; - ctx->optlevel = 3; - ctx->debug = 0; - ctx->ignore_races = false; - ctx->posixly_correct = false; - ctx->status = false; - ctx->unique = false; - ctx->warn = false; - ctx->xargs_safe = false; - - ctx->colors = NULL; - ctx->colors_error = 0; - ctx->cout = NULL; - ctx->cerr = NULL; - - ctx->users = NULL; - ctx->users_error = 0; - ctx->groups = NULL; - ctx->groups_error = 0; - - ctx->mtab = NULL; - ctx->mtab_error = 0; - - trie_init(&ctx->files); - ctx->nfiles = 0; - - struct rlimit rl; - if (getrlimit(RLIMIT_NOFILE, &rl) == 0) { - ctx->nofile_soft = rl.rlim_cur; - ctx->nofile_hard = rl.rlim_max; - } else { - ctx->nofile_soft = 1024; - ctx->nofile_hard = RLIM_INFINITY; - } - - return ctx; -} - -const struct bfs_users *bfs_ctx_users(const struct bfs_ctx *ctx) { - struct bfs_ctx *mut = (struct bfs_ctx *)ctx; - - if (mut->users_error) { - errno = mut->users_error; - } else if (!mut->users) { - mut->users = bfs_users_parse(); - if (!mut->users) { - mut->users_error = errno; - } - } - - return mut->users; -} - -const struct bfs_groups *bfs_ctx_groups(const struct bfs_ctx *ctx) { - struct bfs_ctx *mut = (struct bfs_ctx *)ctx; - - if (mut->groups_error) { - errno = mut->groups_error; - } else if (!mut->groups) { - mut->groups = bfs_groups_parse(); - if (!mut->groups) { - mut->groups_error = errno; - } - } - - return mut->groups; -} - -const struct bfs_mtab *bfs_ctx_mtab(const struct bfs_ctx *ctx) { - struct bfs_ctx *mut = (struct bfs_ctx *)ctx; - - if (mut->mtab_error) { - errno = mut->mtab_error; - } else if (!mut->mtab) { - mut->mtab = bfs_mtab_parse(); - if (!mut->mtab) { - mut->mtab_error = errno; - } - } - - return mut->mtab; -} - -/** - * An open file tracked by the bfs context. - */ -struct bfs_ctx_file { - /** The file itself. */ - CFILE *cfile; - /** The path to the file (for diagnostics). */ - const char *path; -}; - -CFILE *bfs_ctx_dedup(struct bfs_ctx *ctx, CFILE *cfile, const char *path) { - struct bfs_stat sb; - if (bfs_stat(fileno(cfile->file), NULL, 0, &sb) != 0) { - return NULL; - } - - bfs_file_id id; - bfs_stat_id(&sb, &id); - - struct trie_leaf *leaf = trie_insert_mem(&ctx->files, id, sizeof(id)); - if (!leaf) { - return NULL; - } - - struct bfs_ctx_file *ctx_file = leaf->value; - if (ctx_file) { - ctx_file->path = path; - return ctx_file->cfile; - } - - leaf->value = ctx_file = malloc(sizeof(*ctx_file)); - if (!ctx_file) { - trie_remove(&ctx->files, leaf); - return NULL; - } - - ctx_file->cfile = cfile; - ctx_file->path = path; - ++ctx->nfiles; - return cfile; -} - -/** Close a file tracked by the bfs context. */ -static int bfs_ctx_close(struct bfs_ctx *ctx, struct bfs_ctx_file *ctx_file) { - CFILE *cfile = ctx_file->cfile; - - if (cfile == ctx->cout) { - // Will be checked later - return 0; - } else if (cfile == ctx->cerr && !ctx_file->path) { - // Writes to stderr are allowed to fail silently, unless the same file was used by - // -fprint, -fls, etc. - return 0; - } - - int ret = 0, error = 0; - if (ferror(cfile->file)) { - ret = -1; - error = EIO; - } - - if (cfile == ctx->cerr) { - if (fflush(cfile->file) != 0) { - ret = -1; - error = errno; - } - } else { - if (cfclose(cfile) != 0) { - ret = -1; - error = errno; - } - } - - errno = error; - return ret; -} - -int bfs_ctx_free(struct bfs_ctx *ctx) { - int ret = 0; - - if (ctx) { - CFILE *cout = ctx->cout; - CFILE *cerr = ctx->cerr; - - free_expr(ctx->expr); - free_expr(ctx->exclude); - - bfs_mtab_free(ctx->mtab); - - bfs_groups_free(ctx->groups); - bfs_users_free(ctx->users); - - struct trie_leaf *leaf; - while ((leaf = trie_first_leaf(&ctx->files))) { - struct bfs_ctx_file *ctx_file = leaf->value; - - if (bfs_ctx_close(ctx, ctx_file) != 0) { - if (cerr) { - bfs_error(ctx, "'%s': %m.\n", ctx_file->path); - } - ret = -1; - } - - free(ctx_file); - trie_remove(&ctx->files, leaf); - } - trie_destroy(&ctx->files); - - if (cout && fflush(cout->file) != 0) { - if (cerr) { - bfs_error(ctx, "standard output: %m.\n"); - } - ret = -1; - } - - cfclose(cout); - cfclose(cerr); - - free_colors(ctx->colors); - - for (size_t i = 0; i < darray_length(ctx->paths); ++i) { - free((char *)ctx->paths[i]); - } - darray_free(ctx->paths); - - free(ctx->argv); - free(ctx); - } - - return ret; -} |