coreutils
[Top][All Lists]
Advanced

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

[PATCH] dd: support iflag=direct with arbitrary sized files


From: Pádraig Brady
Subject: [PATCH] dd: support iflag=direct with arbitrary sized files
Date: Mon, 16 Oct 2017 00:15:04 -0700

* src/dd.c (iread): Handle read error with a non-aligned
file offset in the O_DIRECT case.
* tests/dd/direct.sh: Test the iflag=direct case also.
* NEWS: Mention the improvement.
---
 NEWS               |  4 ++++
 src/dd.c           | 15 +++++++++++----
 tests/dd/direct.sh |  4 ++--
 3 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/NEWS b/NEWS
index c61e4e8..00cf6df 100644
--- a/NEWS
+++ b/NEWS
@@ -16,6 +16,10 @@ GNU coreutils NEWS                                    -*- 
outline -*-
   to attempt to hide the original length of the file name.
   [bug introduced in coreutils-8.28]
 
+** Improvements
+
+  dd now supports iflag=direct with arbitrary sized files.
+
 ** Build-related
 
   Default man pages are now distributed which are used if perl is
diff --git a/src/dd.c b/src/dd.c
index 636fac6..613dfe0 100644
--- a/src/dd.c
+++ b/src/dd.c
@@ -1108,11 +1108,21 @@ static ssize_t
 iread (int fd, char *buf, size_t size)
 {
   ssize_t nread;
+  static ssize_t prev_nread;
 
   do
     {
       process_signals ();
       nread = read (fd, buf, size);
+      /* Ignore final read error with iflag=direct as that
+         returns EINVAL due to the non aligned file offset.  */
+      if (nread == -1 && errno == EINVAL
+          && 0 < prev_nread && prev_nread < size
+          && (input_flags & O_DIRECT))
+        {
+          errno = 0;
+          nread = 0;
+        }
     }
   while (nread < 0 && errno == EINTR);
 
@@ -1122,8 +1132,6 @@ iread (int fd, char *buf, size_t size)
 
   if (0 < nread && warn_partial_read)
     {
-      static ssize_t prev_nread;
-
       if (0 < prev_nread && prev_nread < size)
         {
           uintmax_t prev = prev_nread;
@@ -1136,10 +1144,9 @@ iread (int fd, char *buf, size_t size)
                    prev);
           warn_partial_read = false;
         }
-
-      prev_nread = nread;
     }
 
+  prev_nread = nread;
   return nread;
 }
 
diff --git a/tests/dd/direct.sh b/tests/dd/direct.sh
index e440ba3..f6bc9ca 100755
--- a/tests/dd/direct.sh
+++ b/tests/dd/direct.sh
@@ -1,5 +1,5 @@
 #!/bin/sh
-# ensure that dd's oflag=direct works
+# ensure that dd's iflag=direct and oflag=direct work
 
 # Copyright (C) 2009-2017 Free Software Foundation, Inc.
 
@@ -29,7 +29,7 @@ truncate -s 8193 p1 || framework_failure_
 
 for i in short m1 p1; do
   rm -f out
-  dd if=$i oflag=direct of=out || fail=1
+  dd if=$i iflag=direct oflag=direct of=out || fail=1
 done
 
 Exit $fail
-- 
2.9.3




reply via email to

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