* src/numfmt.c (process line): Inspect the stdio error state when
outputting each line so that we don't have to check each output function
but do eventually exit upon write error, while also remaining buffered.
(main): Also check when outputting a header for the edge case
of very long headers.
* tests/misc/write-errors.sh: Enable the numfmt test case.
* NEWS: Mention the improvement, and reorganize all numfmt improvements.
---
 NEWS                       | 8 +++++---
 src/numfmt.c               | 8 ++++++--
 tests/misc/write-errors.sh | 2 +-
 3 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/NEWS b/NEWS
index 7641e4f6a..b49b73c54 100644
--- a/NEWS
+++ b/NEWS
@@ -45,9 +45,11 @@ GNU coreutils NEWS                                    -*- 
outline -*-
 
   'install' now uses posix_spawn() to invoke the strip program more 
efficiently.
 
-  numfmt now parses numbers with a non-breaking space character before a unit,
-  and parses numbers containing grouping characters from the current locale.
-  It also supports a multi-byte --delimiter character.
+  'numfmt':
+   - parses numbers with a non-breaking space character before a unit
+   - parses numbers containing grouping characters from the current locale
+   - supports a multi-byte --delimiter character
+   - no longer processes input indefinitely in the presence of write errors
 
   wc -l now operates 10% faster on hosts that support AVX512 instructions.
 
diff --git a/src/numfmt.c b/src/numfmt.c
index 5a1e94570..a2f2be164 100644
--- a/src/numfmt.c
+++ b/src/numfmt.c
@@ -1510,7 +1510,8 @@ process_line (char *line, bool newline)
   }
 
   if (newline)
-    putchar (line_delim);
+    if (ferror (stdout) || putchar (line_delim) < 0)
+      write_error ();
 
   return valid_number;
 }
@@ -1710,7 +1711,10 @@ main (int argc, char **argv)
 
       while (header-- && getdelim (&line, &line_allocated,
                                    line_delim, stdin) > 0)
-        fputs (line, stdout);
+        {
+          if (fputs (line, stdout) == EOF)
+            write_error ();
+        }
 
       while ((len = getdelim (&line, &line_allocated,
                               line_delim, stdin)) > 0)
diff --git a/tests/misc/write-errors.sh b/tests/misc/write-errors.sh
index b30f4f6bd..782ccae5a 100755
--- a/tests/misc/write-errors.sh
+++ b/tests/misc/write-errors.sh
@@ -41,7 +41,7 @@ fold --version; yes | tr -d '\\n' | fold
 head -z -n-1 /dev/zero
 join -a 1 -z /dev/zero /dev/null
 # TODO: nl --version; yes | nl
-# TODO: numfmt --version; yes 1 | numfmt
+numfmt --version; yes 1 | numfmt
 od -v /dev/zero
 paste /dev/zero
 # TODO: pr /dev/zero
-- 
2.51.0


Reply via email to