On 03/02/2011 05:12 AM, Pádraig Brady wrote: > So I'm not sure how to proceed here.
Before worrying about swab, we should at least try to get a warning out for the short-read case we discussed earlier. Here's a revision of my earlier proposal, with a higher-quality warning. Quite possibly we can fold a swab warning into this code later, but one thing at a time. 2011-03-04 Paul Eggert <[email protected]> dd: avoid or diagnose some problems with short reads * src/dd.c (iread): Diagnose short reads when they mess up counts. Derived from a suggestion by Pádraig Brady in: http://lists.gnu.org/archive/html/bug-coreutils/2011-02/msg00150.html diff --git a/NEWS b/NEWS index a367d8d..32cc7b0 100644 --- a/NEWS +++ b/NEWS @@ -39,6 +39,10 @@ GNU coreutils NEWS -*- outline -*- reproduce them efficiently in the output file. mv also benefits when it resorts to copying, e.g., between file systems. + dd bs=BYTES, with either count=BLOCKS or skip=BLOCKS and without + iflag=fullblock, now warns if a short block is read (not at end of + file). This helps avoid confusion when counting or skipping bytes. + join now supports -o 'auto' which will automatically infer the output format from the first line in each file, to ensure the same number of fields are output for each line. diff --git a/src/dd.c b/src/dd.c index daddc1e..39fa3ab 100644 --- a/src/dd.c +++ b/src/dd.c @@ -796,14 +796,43 @@ process_signals (void) static ssize_t iread (int fd, char *buf, size_t size) { - while (true) + ssize_t nread; + + do { - ssize_t nread; process_signals (); nread = read (fd, buf, size); - if (! (nread < 0 && errno == EINTR)) - return nread; } + while (nread < 0 && errno == EINTR); + + if (0 < nread) + { + /* If bs=SIZE is given and iflag=fullblock is not, warn if a + short block was read (not at EOF), and either count=BLOCKS or + skip=BLOCKS is also given. This helps avoid confusion when + counting or skipping bytes. */ + static bool warned; + static ssize_t prev_nread; + + if (! warned && iread_fnc == iread + && 0 < prev_nread && prev_nread < size + && (skip_records + || (0 < max_records && max_records < (uintmax_t) -1))) + { + uintmax_t prev = prev_nread; + error (0, 0, ngettext (("warning: short read (%"PRIuMAX" byte); " + "suggest iflag=fullblock"), + ("warning: short read (%"PRIuMAX" bytes); " + "suggest iflag=fullblock"), + select_plural (prev)), + prev); + warned = true; + } + + prev_nread = nread; + } + + return nread; } /* Wrapper around iread function to accumulate full blocks. */
