bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#7362: dd strangeness


From: Paul Eggert
Subject: bug#7362: dd strangeness
Date: Thu, 03 Mar 2011 23:44:15 -0800
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.14) Gecko/20110223 Thunderbird/3.1.8

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  <address@hidden>

        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.  */





reply via email to

[Prev in Thread] Current Thread [Next in Thread]