]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
shred: avoid a data pass on empty files
authorPádraig Brady <P@draigBrady.com>
Thu, 3 Apr 2014 12:47:48 +0000 (13:47 +0100)
committerPádraig Brady <P@draigBrady.com>
Fri, 4 Apr 2014 04:32:41 +0000 (05:32 +0100)
* src/shred.c (do_wipefd): Don't increase the size written
for an empty file up to a full block.  Also increase the size
to OFF_T_MAX in the edge case where we do overflow.
* NEWS: Mention the shred improvements from recent changes.
* tests/misc/shred-passes.sh: Adjust as we no longer
write a BLKSIZE of data for empty files.

NEWS
src/shred.c
tests/misc/shred-passes.sh

diff --git a/NEWS b/NEWS
index d6aa885956cc6286dfbe1e937ee9fe9e808f192b..c6451b289863e364503ecfa6fa66fc2165431498 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -57,6 +57,9 @@ GNU coreutils NEWS                                    -*- outline -*-
   causing name look-up errors.  Also look-ups are first done outside the chroot,
   in case the look-up within the chroot fails due to library conflicts etc.
 
+  shred now supports multiple passes on GNU/Linux tape devices by rewinding
+  the tape before each pass.  Also redundant writes to empty files are avoided.
+
   split avoids unnecessary input buffering, immediately writing input to output
   which is significant with --filter or when writing to fifos or stdout etc.
 
index 732d3afb1ac99140c320c63872211a8865812e37..ed370513dd00bbf2a3c27d5de8f6cda446cecea6 100644 (file)
@@ -428,7 +428,7 @@ dopass (int fd, struct stat const *st, char const *qname, off_t *sizep,
   size_t soff;                 /* Offset into buffer for next write */
   ssize_t ssize;               /* Return value from write */
 
-  /* Do nothing for --size=0 or regular empty files with --exact.  */
+  /* Do nothing for --size=0 or regular empty files.  */
   if (size == 0)
     return 0;
 
@@ -887,15 +887,15 @@ do_wipefd (int fd, char const *qname, struct randint_source *s,
 
           if (! flags->exact)
             {
-              /* Round up to the nearest blocksize.  If the file is
-                 empty output a block anyway, in case the file system
-                 stores small files in the inode.  */
+              /* Round up to the nearest blocksize to clear slack space.  */
               off_t remainder = size % ST_BLKSIZE (st);
-              if (remainder != 0 || size == 0)
+              if (remainder != 0)
                 {
                   off_t size_incr = ST_BLKSIZE (st) - remainder;
                   if (! INT_ADD_OVERFLOW (size, size_incr))
                     size += size_incr;
+                  else
+                    size = OFF_T_MAX;
                 }
             }
         }
index bbd12880c9d191fb1d3e7200dfd1a6b28c419784..268af950f798cc9e949b9965904c81914953569d 100755 (executable)
@@ -20,9 +20,9 @@
 print_ver_ shred
 
 
-# shred a single letter, zero length file which should result in
+# shred a single letter, which should result in
 # 3 random passes and a single rename.
-touch f || framework_failure_
+printf 1 > f || framework_failure_
 echo "\
 shred: f: pass 1/3 (random)...
 shred: f: pass 2/3 (random)...
@@ -35,15 +35,15 @@ shred -v -u f 2>out || fail=1
 
 compare exp out || fail=1
 
-# Likewise but with --exact to bypass the
-# data passes for the zero length file
+# Likewise but for a zero length file
+# to bypass the data passes
 touch f || framework_failure_
 echo "\
 shred: f: removing
 shred: f: renamed to 0
 shred: f: removed" > exp || framework_failure_
 
-shred -x -v -u f 2>out || fail=1
+shred -v -u f 2>out || fail=1
 
 compare exp out || fail=1