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


Reply via email to