diff options
author | Tavian Barnes <tavianator@tavianator.com> | 2021-09-21 11:56:02 -0400 |
---|---|---|
committer | Tavian Barnes <tavianator@tavianator.com> | 2021-09-21 11:56:02 -0400 |
commit | 5353347f23f4a0cb044d1d87d7747dedc71f525c (patch) | |
tree | aed48680549c5f062f2f9bea8eae9ad5cb46fded /parse.c | |
parent | 4bcb10a88e3d282494642c1fa10140b42f501e97 (diff) | |
download | bfs-5353347f23f4a0cb044d1d87d7747dedc71f525c.tar.xz |
ctx: Also deduplicate the standard streams
This fixes some potential missing output when the same file is used in a
redirection and something like -fprint. The main benefit is smarter
handling of /dev/stdout, which will now share the CFILE* with cout.
Diffstat (limited to 'parse.c')
-rw-r--r-- | parse.c | 21 |
1 files changed, 19 insertions, 2 deletions
@@ -334,12 +334,24 @@ static void init_print_expr(struct parser_state *state, struct expr *expr) { static int expr_open(struct parser_state *state, struct expr *expr, const char *path) { struct bfs_ctx *ctx = state->ctx; - expr->cfile = bfs_ctx_open(ctx, path, state->use_color); - if (!expr->cfile) { + CFILE *cfile = cfopen(path, state->use_color ? ctx->colors : NULL); + if (!cfile) { parse_error(state, "${blu}%s${rs} ${bld}%s${rs}: %m.\n", expr->argv[0], path); return -1; } + CFILE *dedup = bfs_ctx_dedup(ctx, cfile, path); + if (!dedup) { + parse_error(state, "${blu}%s${rs} ${bld}%s${rs}: %m.\n", expr->argv[0], path); + cfclose(cfile); + return -1; + } + + expr->cfile = dedup; + + if (dedup != cfile) { + cfclose(cfile); + } return 0; } @@ -3689,6 +3701,11 @@ struct bfs_ctx *bfs_parse_cmdline(int argc, char *argv[]) { goto fail; } + if (!bfs_ctx_dedup(ctx, ctx->cout, NULL) || !bfs_ctx_dedup(ctx, ctx->cerr, NULL)) { + bfs_perror(ctx, "bfs_ctx_dedup()"); + goto fail; + } + bool stdin_tty = isatty(STDIN_FILENO); bool stdout_tty = isatty(STDOUT_FILENO); bool stderr_tty = isatty(STDERR_FILENO); |