]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
maint: refactor copy to use is_nul()
authorPádraig Brady <P@draigBrady.com>
Thu, 1 Mar 2012 11:56:41 +0000 (11:56 +0000)
committerPádraig Brady <P@draigBrady.com>
Tue, 6 Mar 2012 23:43:21 +0000 (23:43 +0000)
* src/dd.c: Move is_nul() from here to ...
* src/system.h: ... here
* src/copy.c (sparse_copy): Adjust to use the refactored is_nul()

src/copy.c
src/dd.c
src/system.h

index 541ca20cb67c9154b658ae2ed1d396d766ebe88b..f63a726961b0f2153d5d51f9b5114e7d6b403855 100644 (file)
@@ -152,13 +152,12 @@ sparse_copy (int src_fd, int dest_fd, char *buf, size_t buf_size,
              uintmax_t max_n_read, off_t *total_n_read,
              bool *last_write_made_hole)
 {
-  typedef uintptr_t word;
   *last_write_made_hole = false;
   *total_n_read = 0;
 
   while (max_n_read)
     {
-      word *wp = NULL;
+      bool make_hole = false;
 
       ssize_t n_read = read (src_fd, buf, MIN (max_n_read, buf_size));
       if (n_read < 0)
@@ -175,11 +174,10 @@ sparse_copy (int src_fd, int dest_fd, char *buf, size_t buf_size,
 
       if (make_holes)
         {
-          char *cp;
-
-          /* Sentinel to stop loop.  */
+          /* Sentinel required by is_nul().  */
           buf[n_read] = '\1';
 #ifdef lint
+          typedef uintptr_t word;
           /* Usually, buf[n_read] is not the byte just before a "word"
              (aka uintptr_t) boundary.  In that case, the word-oriented
              test below (*wp++ == 0) would read some uninitialized bytes
@@ -189,35 +187,17 @@ sparse_copy (int src_fd, int dest_fd, char *buf, size_t buf_size,
           memset (buf + n_read + 1, 0, sizeof (word) - 1);
 #endif
 
-          /* Find first nonzero *word*, or the word with the sentinel.  */
-
-          wp = (word *) buf;
-          while (*wp++ == 0)
-            continue;
-
-          /* Find the first nonzero *byte*, or the sentinel.  */
-
-          cp = (char *) (wp - 1);
-          while (*cp++ == 0)
-            continue;
-
-          if (cp <= buf + n_read)
-            /* Clear to indicate that a normal write is needed. */
-            wp = NULL;
-          else
+          if ((make_hole = is_nul (buf, n_read)))
             {
-              /* We found the sentinel, so the whole input block was zero.
-                 Make a hole.  */
               if (lseek (dest_fd, n_read, SEEK_CUR) < 0)
                 {
                   error (0, errno, _("cannot lseek %s"), quote (dst_name));
                   return false;
                 }
-              *last_write_made_hole = true;
             }
         }
 
-      if (!wp)
+      if (!make_hole)
         {
           size_t n = n_read;
           if (full_write (dest_fd, buf, n) != n)
@@ -225,13 +205,14 @@ sparse_copy (int src_fd, int dest_fd, char *buf, size_t buf_size,
               error (0, errno, _("writing %s"), quote (dst_name));
               return false;
             }
-          *last_write_made_hole = false;
 
           /* It is tempting to return early here upon a short read from a
              regular file.  That would save the final read syscall for each
              file.  Unfortunately that doesn't work for certain files in
              /proc with linux kernels from at least 2.6.9 .. 2.6.29.  */
         }
+
+      *last_write_made_hole = make_hole;
     }
 
   return true;
index 1bca0d6f3fb7e30f81e935284a4726775cb276b2..4626de2ab74efa02b12496e3eca6356cab852ca9 100644 (file)
--- a/src/dd.c
+++ b/src/dd.c
@@ -997,27 +997,6 @@ iread_fullblock (int fd, char *buf, size_t size)
   return nread;
 }
 
-/* Return whether the buffer consists entirely of NULs.
-   Note the word after the buffer must be non NUL. */
-
-static bool _GL_ATTRIBUTE_PURE
-is_nul (const char *buf, size_t bufsize)
-{
-  typedef uintptr_t word;
-
-  /* Find first nonzero *word*, or the word with the sentinel.  */
-  word *wp = (word *) buf;
-  while (*wp++ == 0)
-    continue;
-
-  /* Find the first nonzero *byte*, or the sentinel.  */
-  char *cp = (char *) (wp - 1);
-  while (*cp++ == 0)
-    continue;
-
-  return cp > buf + bufsize;
-}
-
 /* Write to FD the buffer BUF of size SIZE, processing any signals
    that arrive.  Return the number of bytes written, setting errno if
    this is less than SIZE.  Keep trying if there are partial
index f312f88d04e0883f14551bbdae6ac69e65b6c9e6..49cd08a3b0f14fc6e08bced016f2c0910ac4f372 100644 (file)
@@ -491,6 +491,27 @@ ptr_align (void const *ptr, size_t alignment)
   return (void *) (p1 - (size_t) p1 % alignment);
 }
 
+/* Return whether the buffer consists entirely of NULs.
+   Note the word after the buffer must be non NUL. */
+
+static inline bool _GL_ATTRIBUTE_PURE
+is_nul (const char *buf, size_t bufsize)
+{
+  typedef uintptr_t word;
+
+  /* Find first nonzero *word*, or the word with the sentinel.  */
+  word *wp = (word *) buf;
+  while (*wp++ == 0)
+    continue;
+
+  /* Find the first nonzero *byte*, or the sentinel.  */
+  char *cp = (char *) (wp - 1);
+  while (*cp++ == 0)
+    continue;
+
+  return cp > buf + bufsize;
+}
+
 /* If 10*Accum + Digit_val is larger than the maximum value for Type,
    then don't update Accum and return false to indicate it would
    overflow.  Otherwise, set Accum to that new value and return true.