From b1df1d557eb8e3c40778a01af9cd972c80a19d95 Mon Sep 17 00:00:00 2001 From: =?utf8?q?P=C3=A1draig=20Brady?=
Date: Sat, 15 Jul 2023 21:43:07 +0100 Subject: [PATCH] comm: promptly diagnose write errors * src/comm.c (writeline): Simplify by removing the unneeded STREAM parameter. Call write_error() upon ferror(). (compare_files): Adjust to simplified writeline(). * tests/misc/write-errors.sh: Enable comm test. * NEWS: Mention the improvement. --- NEWS | 4 ++-- src/comm.c | 21 ++++++++++++--------- tests/misc/write-errors.sh | 2 +- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/NEWS b/NEWS index 8d15f27382..24c018374e 100644 --- a/NEWS +++ b/NEWS @@ -62,8 +62,8 @@ GNU coreutils NEWS -*- outline -*- irrespective of which kernel version coreutils is built against, reinstating that behaviour from coreutils-9.0. - cut, od, and uniq will now exit immediately upon receiving a write error, - which is significant when reading large / unbounded inputs. + comm, cut, od, and uniq will now exit immediately upon receiving a + write error, which is significant when reading large / unbounded inputs. split now uses more tuned access patterns for its potentially large input. This was seen to improve throughput by 5% when reading from SSD. diff --git a/src/comm.c b/src/comm.c index 12fa9c9eaa..5cb2410e58 100644 --- a/src/comm.c +++ b/src/comm.c @@ -163,13 +163,13 @@ Examples:\n\ exit (status); } -/* Output the line in linebuffer LINE to stream STREAM +/* Output the line in linebuffer LINE to stdout provided the switches say it should be output. CLASS is 1 for a line found only in file 1, 2 for a line only in file 2, 3 for a line in both. */ static void -writeline (struct linebuffer const *line, FILE *stream, int class) +writeline (struct linebuffer const *line, int class) { switch (class) { @@ -182,20 +182,23 @@ writeline (struct linebuffer const *line, FILE *stream, int class) if (!only_file_2) return; if (only_file_1) - fwrite (col_sep, 1, col_sep_len, stream); + fwrite (col_sep, 1, col_sep_len, stdout); break; case 3: if (!both) return; if (only_file_1) - fwrite (col_sep, 1, col_sep_len, stream); + fwrite (col_sep, 1, col_sep_len, stdout); if (only_file_2) - fwrite (col_sep, 1, col_sep_len, stream); + fwrite (col_sep, 1, col_sep_len, stdout); break; } - fwrite (line->buffer, sizeof (char), line->length, stream); + fwrite (line->buffer, sizeof (char), line->length, stdout); + + if (ferror (stdout)) + write_error (); } /* Check that successive input lines PREV and CURRENT from input file @@ -329,7 +332,7 @@ compare_files (char **infiles) { /* Line is seen in both files. */ total[2]++; - writeline (thisline[1], stdout, 3); + writeline (thisline[1], 3); } else { @@ -338,13 +341,13 @@ compare_files (char **infiles) { /* Line is seen in file 1 only. */ total[0]++; - writeline (thisline[0], stdout, 1); + writeline (thisline[0], 1); } else { /* Line is seen in file 2 only. */ total[1]++; - writeline (thisline[1], stdout, 2); + writeline (thisline[1], 2); } } diff --git a/tests/misc/write-errors.sh b/tests/misc/write-errors.sh index e217c5512b..a9e112c3a8 100755 --- a/tests/misc/write-errors.sh +++ b/tests/misc/write-errors.sh @@ -27,7 +27,7 @@ fi # First word in command line is checked against built programs echo "\ cat /dev/zero -# TODO: comm -z /dev/zero /dev/zero +comm -z /dev/zero /dev/zero cut -z -c1- /dev/zero cut -z -f1- /dev/zero dd if=/dev/zero -- 2.47.2