From c4676b38309bba5d24efeb22f52fbeaace7dcbe2 Mon Sep 17 00:00:00 2001 From: Tavian Barnes Date: Sun, 13 Mar 2022 14:35:43 -0400 Subject: ctx: Factor out exec flushing behaviour into bfs_ctx_flush() --- ctx.c | 21 ++++++++++++++++----- ctx.h | 10 +++++++++- exec.c | 10 ++-------- 3 files changed, 27 insertions(+), 14 deletions(-) diff --git a/ctx.c b/ctx.c index 236094c..15e7f4b 100644 --- a/ctx.c +++ b/ctx.c @@ -197,8 +197,19 @@ CFILE *bfs_ctx_dedup(struct bfs_ctx *ctx, CFILE *cfile, const char *path) { return cfile; } +void bfs_ctx_flush(const struct bfs_ctx *ctx) { + // Before executing anything, flush all open streams. This ensures that + // - the user sees everything relevant before an -ok[dir] prompt + // - output from commands is interleaved consistently with bfs + // - executed commands can rely on I/O from other bfs actions + // + // We do not check errors here, but they will be caught at cleanup time + // with ferror(). + fflush(NULL); +} + /** Flush a file and report any errors. */ -static int bfs_ctx_flush(CFILE *cfile) { +static int bfs_ctx_fflush(CFILE *cfile) { int ret = 0, error = 0; if (ferror(cfile->file)) { ret = -1; @@ -214,7 +225,7 @@ static int bfs_ctx_flush(CFILE *cfile) { } /** Close a file tracked by the bfs context. */ -static int bfs_ctx_close(struct bfs_ctx *ctx, struct bfs_ctx_file *ctx_file) { +static int bfs_ctx_fclose(struct bfs_ctx *ctx, struct bfs_ctx_file *ctx_file) { CFILE *cfile = ctx_file->cfile; if (cfile == ctx->cout) { @@ -224,7 +235,7 @@ static int bfs_ctx_close(struct bfs_ctx *ctx, struct bfs_ctx_file *ctx_file) { // Writes to stderr are allowed to fail silently, unless the same file was used by // -fprint, -fls, etc. if (ctx_file->path) { - return bfs_ctx_flush(cfile); + return bfs_ctx_fflush(cfile); } else { return 0; } @@ -263,7 +274,7 @@ int bfs_ctx_free(struct bfs_ctx *ctx) { while ((leaf = trie_first_leaf(&ctx->files))) { struct bfs_ctx_file *ctx_file = leaf->value; - if (bfs_ctx_close(ctx, ctx_file) != 0) { + if (bfs_ctx_fclose(ctx, ctx_file) != 0) { if (cerr) { bfs_error(ctx, "'%s': %m.\n", ctx_file->path); } @@ -275,7 +286,7 @@ int bfs_ctx_free(struct bfs_ctx *ctx) { } trie_destroy(&ctx->files); - if (cout && bfs_ctx_flush(cout) != 0) { + if (cout && bfs_ctx_fflush(cout) != 0) { if (cerr) { bfs_error(ctx, "standard output: %m.\n"); } diff --git a/ctx.h b/ctx.h index 02d296f..8f8101d 100644 --- a/ctx.h +++ b/ctx.h @@ -1,6 +1,6 @@ /**************************************************************************** * bfs * - * Copyright (C) 2015-2021 Tavian Barnes * + * Copyright (C) 2015-2022 Tavian Barnes * * * * Permission to use, copy, modify, and/or distribute this software for any * * purpose with or without fee is hereby granted. * @@ -178,6 +178,14 @@ const struct bfs_mtab *bfs_ctx_mtab(const struct bfs_ctx *ctx); */ struct CFILE *bfs_ctx_dedup(struct bfs_ctx *ctx, struct CFILE *cfile, const char *path); +/** + * Flush any caches for consistency with external processes. + * + * @param ctx + * The bfs context. + */ +void bfs_ctx_flush(const struct bfs_ctx *ctx); + /** * Dump the parsed command line. * diff --git a/exec.c b/exec.c index 505e51c..85c472c 100644 --- a/exec.c +++ b/exec.c @@ -325,14 +325,8 @@ static void bfs_exec_closewd(struct bfs_exec *execbuf, const struct BFTW *ftwbuf /** Actually spawn the process. */ static int bfs_exec_spawn(const struct bfs_exec *execbuf) { - // Before executing anything, flush all open streams. This ensures that - // - the user sees everything relevant before an -ok[dir] prompt - // - output from commands is interleaved consistently with bfs - // - executed commands can rely on I/O from other bfs actions - // - // We do not check errors here, but they will be caught at cleanup time - // with ferror(). - fflush(NULL); + // Flush the context state for consistency with the external process + bfs_ctx_flush(execbuf->ctx); if (execbuf->flags & BFS_EXEC_CONFIRM) { for (size_t i = 0; i < execbuf->argc; ++i) { -- cgit v1.2.3