This patch also fixes a bug where 'tac' would print a vague error on
some inputs:
$ seq 10000 | ./src/tac-prev > /dev/full
tac-prev: write error
$ seq 10000 | ./src/tac > /dev/full
tac: write error: No space left on device
In this case ferror (stdout) is true, but errno has been set back to
zero by a successful fclose (stdout) call.
* src/tac.c (output): Call write_error() if fwrite fails.
* tests/misc/write-errors.sh: Add a 'tac' invocation so that the error
message is checked.
* NEWS: Mention the improvement.
---
NEWS | 3 +++
src/tac.c | 6 ++++--
tests/misc/write-errors.sh | 1 +
3 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/NEWS b/NEWS
index 42d1f2e2e..2fabd07b7 100644
--- a/NEWS
+++ b/NEWS
@@ -59,6 +59,9 @@ GNU coreutils NEWS -*-
outline -*-
'shuf -i' now operates up to two times faster on systems with unlocked stdio
functions.
+ 'tac' will now exit sooner after a write error, which is significant when
+ operating on a file with many lines.
+
'timeout' now properly detects when it is reparented by a subreaper process
on
Linux instead of init, e.g., the 'systemd --user' process.
diff --git a/src/tac.c b/src/tac.c
index 4cab99d0b..e63f70fc3 100644
--- a/src/tac.c
+++ b/src/tac.c
@@ -158,7 +158,8 @@ output (char const *start, char const *past_end)
if (!start)
{
- fwrite (buffer, 1, bytes_in_buffer, stdout);
+ if (fwrite (buffer, 1, bytes_in_buffer, stdout) != bytes_in_buffer)
+ write_error ();
bytes_in_buffer = 0;
return;
}
@@ -169,7 +170,8 @@ output (char const *start, char const *past_end)
memcpy (buffer + bytes_in_buffer, start, bytes_available);
bytes_to_add -= bytes_available;
start += bytes_available;
- fwrite (buffer, 1, WRITESIZE, stdout);
+ if (fwrite (buffer, 1, WRITESIZE, stdout) != WRITESIZE)
+ write_error ();
bytes_in_buffer = 0;
bytes_available = WRITESIZE;
}
diff --git a/tests/misc/write-errors.sh b/tests/misc/write-errors.sh
index 53111417a..4ecafd626 100755
--- a/tests/misc/write-errors.sh
+++ b/tests/misc/write-errors.sh
@@ -57,6 +57,7 @@ pr /dev/zero
pr --version; yes 1 | pr
seq inf
shuf -i 0-1 -r
+tac --version; seq 10000 | tac
tail -n+1 -z /dev/zero
tee < /dev/zero
tr . . < /dev/zero
--
2.53.0