From a03c00023a700386453b91142116279bb79fb59d Mon Sep 17 00:00:00 2001 From: =?utf8?q?P=C3=A1draig=20Brady?= Date: Tue, 11 Jul 2023 12:46:50 +0100 Subject: [PATCH] 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 --- NEWS | 3 +++ src/od.c | 8 ++++++-- tests/misc/write-errors.sh | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) 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 -- 2.47.2