summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--exec.c9
-rwxr-xr-xtests.sh38
-rw-r--r--tests/test_exec_flush.out19
-rw-r--r--tests/test_exec_flush_fprint.out1
-rw-r--r--tests/test_exec_plus_flush.out1
5 files changed, 67 insertions, 1 deletions
diff --git a/exec.c b/exec.c
index 310756b..4cfb2e0 100644
--- a/exec.c
+++ b/exec.c
@@ -325,6 +325,15 @@ 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);
+
if (execbuf->flags & BFS_EXEC_CONFIRM) {
for (size_t i = 0; i < execbuf->argc; ++i) {
fprintf(stderr, "%s ", execbuf->argv[i]);
diff --git a/tests.sh b/tests.sh
index 25517ca..ed502fd 100755
--- a/tests.sh
+++ b/tests.sh
@@ -2,7 +2,7 @@
############################################################################
# bfs #
-# Copyright (C) 2015-2021 Tavian Barnes <tavianator@tavianator.com> #
+# Copyright (C) 2015-2022 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. #
@@ -492,6 +492,12 @@ gnu_tests=(
test_exec_nothing
test_exec_substring
+ test_exec_flush
+ test_exec_flush_fail
+ test_exec_flush_fprint
+ test_exec_flush_fprint_fail
+ test_exec_plus_flush
+ test_exec_plus_flush_fail
test_execdir
test_execdir_substring
@@ -1754,6 +1760,36 @@ function test_exec_substring() {
bfs_diff basic -exec echo '-{}-' ';'
}
+function test_exec_flush() {
+ # IO streams should be flushed before executing programs
+ bfs_diff basic -printf '%p ' -exec echo found \;
+}
+
+function test_exec_flush_fail() {
+ # Failure to flush streams before exec should be caught
+ skip_if test ! -e /dev/full
+ fail quiet invoke_bfs basic -printf '%p ' -exec true \; >/dev/full
+}
+
+function test_exec_flush_fprint() {
+ # Even non-stdstreams should be flushed
+ bfs_diff basic/a -fprint scratch/foo -exec cat scratch/foo \;
+}
+
+function test_exec_flush_fprint_fail() {
+ skip_if test ! -e /dev/full
+ fail quiet invoke_bfs basic/a -fprint /dev/full -exec true \;
+}
+
+function test_exec_plus_flush() {
+ bfs_diff basic/a -printf '%p ' -exec echo found {} +
+}
+
+function test_exec_plus_flush_fail() {
+ skip_if test ! -e /dev/full
+ fail quiet invoke_bfs basic/a -printf '%p ' -exec echo found {} + >/dev/full
+}
+
function test_execdir() {
bfs_diff basic -execdir echo '{}' ';'
}
diff --git a/tests/test_exec_flush.out b/tests/test_exec_flush.out
new file mode 100644
index 0000000..0e6234a
--- /dev/null
+++ b/tests/test_exec_flush.out
@@ -0,0 +1,19 @@
+basic found
+basic/a found
+basic/b found
+basic/c found
+basic/e found
+basic/g found
+basic/i found
+basic/j found
+basic/k found
+basic/l found
+basic/c/d found
+basic/e/f found
+basic/g/h found
+basic/j/foo found
+basic/k/foo found
+basic/l/foo found
+basic/k/foo/bar found
+basic/l/foo/bar found
+basic/l/foo/bar/baz found
diff --git a/tests/test_exec_flush_fprint.out b/tests/test_exec_flush_fprint.out
new file mode 100644
index 0000000..511198f
--- /dev/null
+++ b/tests/test_exec_flush_fprint.out
@@ -0,0 +1 @@
+basic/a
diff --git a/tests/test_exec_plus_flush.out b/tests/test_exec_plus_flush.out
new file mode 100644
index 0000000..7c587ba
--- /dev/null
+++ b/tests/test_exec_plus_flush.out
@@ -0,0 +1 @@
+basic/a found basic/a