summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPádraig Brady <P@draigBrady.com>2014-04-03 13:47:48 +0100
committerPádraig Brady <P@draigBrady.com>2014-04-04 05:32:41 +0100
commit217618e8bf10a09270291b9825f3181ed2f83dbf (patch)
tree2dda4cac20c6f65fee545800279cf5f995ede4fa
parentd0294ff3b90430750a631556277c75f1a555dd44 (diff)
downloadcoreutils-217618e8bf10a09270291b9825f3181ed2f83dbf.tar.xz
shred: avoid a data pass on empty files
* 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.
-rw-r--r--NEWS3
-rw-r--r--src/shred.c10
-rwxr-xr-xtests/misc/shred-passes.sh10
3 files changed, 13 insertions, 10 deletions
diff --git a/NEWS b/NEWS
index d6aa88595..c6451b289 100644
--- 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.
diff --git a/src/shred.c b/src/shred.c
index 732d3afb1..ed370513d 100644
--- a/src/shred.c
+++ b/src/shred.c
@@ -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;
}
}
}
diff --git a/tests/misc/shred-passes.sh b/tests/misc/shred-passes.sh
index bbd12880c..268af950f 100755
--- a/tests/misc/shred-passes.sh
+++ b/tests/misc/shred-passes.sh
@@ -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