From: Pádraig Brady Date: Tue, 11 Jul 2023 11:46:50 +0000 (+0100) Subject: od: promptly diagnose write errors X-Git-Tag: v9.4~76 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a03c00023a700386453b91142116279bb79fb59d;p=thirdparty%2Fcoreutils.git od: promptly diagnose write errors * src/od.c (dump): Check for write errors after each block written, to exit early even with large / unbounded inputs. * tests/misc/write-errors.sh: enable od check. * NEWS: Mention the improvement. Fixes https://bugs.gnu.org/64540 --- diff --git a/NEWS b/NEWS index 35ae02a8eb..892db27b8d 100644 --- a/NEWS +++ b/NEWS @@ -62,6 +62,9 @@ GNU coreutils NEWS -*- outline -*- irrespective of which kernel version coreutils is built against, reinstating that behaviour from coreutils-9.0. + od 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/od.c b/src/od.c index 6b66ceb4fb..cde483c984 100644 --- a/src/od.c +++ b/src/od.c @@ -1380,7 +1380,7 @@ dump (void) if (limit_bytes_to_format) { - while (true) + while (ok) { size_t n_needed; if (current_offset >= end_offset) @@ -1396,13 +1396,15 @@ dump (void) affirm (n_bytes_read == bytes_per_block); write_block (current_offset, n_bytes_read, block[!idx], block[idx]); + if (ferror (stdout)) + ok = false; current_offset += n_bytes_read; idx = !idx; } } else { - while (true) + while (ok) { ok &= read_block (bytes_per_block, block[idx], &n_bytes_read); if (n_bytes_read < bytes_per_block) @@ -1410,6 +1412,8 @@ dump (void) affirm (n_bytes_read == bytes_per_block); write_block (current_offset, n_bytes_read, block[!idx], block[idx]); + if (ferror (stdout)) + ok = false; current_offset += n_bytes_read; idx = !idx; } diff --git a/tests/misc/write-errors.sh b/tests/misc/write-errors.sh index a1ba2deb14..31b6433d7b 100755 --- a/tests/misc/write-errors.sh +++ b/tests/misc/write-errors.sh @@ -38,7 +38,7 @@ head -z -n-1 /dev/zero # TODO: join -a 1 -z /dev/zero /dev/null # TODO: nl --version; yes | nl # TODO: numfmt --version; yes 1 | numfmt -# TODO: od -v /dev/zero +od -v /dev/zero paste /dev/zero # TODO: pr /dev/zero seq inf