summaryrefslogtreecommitdiffstats
path: root/parse.c
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2021-09-21 11:56:02 -0400
committerTavian Barnes <tavianator@tavianator.com>2021-09-21 11:56:02 -0400
commit5353347f23f4a0cb044d1d87d7747dedc71f525c (patch)
treeaed48680549c5f062f2f9bea8eae9ad5cb46fded /parse.c
parent4bcb10a88e3d282494642c1fa10140b42f501e97 (diff)
downloadbfs-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.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/parse.c b/parse.c
index 9930c8b..ad8e89c 100644
--- a/parse.c
+++ b/parse.c
@@ -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);