dd: fix issues in the count_bytes and seek_bytes flags change
authorPádraig Brady <P@draigBrady.com>
Mon, 13 Feb 2012 21:47:28 +0000 (21:47 +0000)
committerPádraig Brady <P@draigBrady.com>
Mon, 13 Feb 2012 21:58:21 +0000 (21:58 +0000)
These edge cases were missed in the previous commit 140eca15c.

* src/dd.c (main): Include the bytes slop when truncating
without further I/O.  Don't invalidate the whole file cache
in the case where 0 < count < ibs.
* tests/dd/bytes: Change to using the independent truncate
command to generate the file for comparison.  Remove a redundant
test case and replace with one testing the truncation only logic.

src/dd.c
tests/dd/bytes

index e7f4037..fe44a30 100644 (file)
--- a/src/dd.c
+++ b/src/dd.c
@@ -1917,7 +1917,7 @@ dd_copy (void)
 
   while (1)
     {
-      if (r_partial + r_full >= max_records + (max_bytes ? 1 : 0))
+      if (r_partial + r_full >= max_records + !!max_bytes)
         break;
 
       /* Zero the buffer before reading, so that if we get a read error,
@@ -2170,7 +2170,7 @@ main (int argc, char **argv)
 
       if (seek_records != 0 && !(conversions_mask & C_NOTRUNC))
         {
-          uintmax_t size = seek_records * output_blocksize;
+          uintmax_t size = seek_records * output_blocksize + seek_bytes;
           unsigned long int obs = output_blocksize;
 
           if (OFF_T_MAX / output_blocksize < seek_records)
@@ -2207,7 +2207,7 @@ main (int argc, char **argv)
 
   exit_status = dd_copy ();
 
-  if (max_records == 0)
+  if (max_records == 0 && max_bytes == 0)
     {
       /* Special case to invalidate cache to end of file.  */
       if (i_nocache && !invalidate_cache (STDIN_FILENO, 0))
@@ -2225,7 +2225,7 @@ main (int argc, char **argv)
     }
   else if (max_records != (uintmax_t) -1)
     {
-      /* Invalidate any pending region less that page size,
+      /* Invalidate any pending region less than page size,
          in case the kernel might round up.  */
       if (i_nocache)
         invalidate_cache (STDIN_FILENO, 0);
index 6038742..15755aa 100755 (executable)
@@ -45,13 +45,12 @@ esac
 # seek bytes
 echo abcdefghijklm |
  dd bs=5 seek=8 oflag=seek_bytes > out 2> /dev/null || fail=1
-echo abcdefghijklm |
- dd bs=4 seek=2 > expected 2> /dev/null || fail=1
+printf '\0\0\0\0\0\0\0\0abcdefghijklm\n' > expected
 compare expected out || fail=1
 
-# seek bytes on empty file
-echo abcdefghijklm |
- dd bs=5 seek=8 oflag=seek_bytes > out2 2> /dev/null || fail=1
-compare expected out2 || fail=1
+# Just truncation, no I/O
+dd bs=5 seek=8 oflag=seek_bytes of=out2 count=0 2> /dev/null || fail=1
+truncate -s8 expected2
+compare expected2 out2 || fail=1
 
 Exit $fail