From: Pádraig Brady Date: Sat, 15 Jul 2023 20:43:07 +0000 (+0100) Subject: comm: promptly diagnose write errors X-Git-Tag: v9.4~73 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b1df1d557eb8e3c40778a01af9cd972c80a19d95;p=thirdparty%2Fcoreutils.git 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. --- 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