summaryrefslogtreecommitdiff
path: root/src/shred.c
diff options
context:
space:
mode:
authorJim Meyering <jim@meyering.net>2000-10-28 11:49:52 +0000
committerJim Meyering <jim@meyering.net>2000-10-28 11:49:52 +0000
commit37c05b6267140d4afd11ad96cc244e8cd851083c (patch)
tree23cdfaa3c63b83eb03d1e29ec86f56ac71d904f6 /src/shred.c
parent37bcdce62a583c352176d09d7d2d5f7fd2149ae7 (diff)
downloadcoreutils-37c05b6267140d4afd11ad96cc244e8cd851083c.tar.xz
Include assert.h.
(fillrand): Add a parameter, size_max. Add an assertion. Adjust caller. (dopass): Break out of the `for (;;)' loop if size < offset. That can happen now that dopass is called with SIZE == -1. (do_wipefd): Accept a length of zero only for a regular file. If lseek fails or returns 0 for a non-regular file, let dopass determine the length. Inspired by a patch from Alan Iwi.
Diffstat (limited to 'src/shred.c')
-rw-r--r--src/shred.c40
1 files changed, 30 insertions, 10 deletions
diff --git a/src/shred.c b/src/shred.c
index c523d097b..9c1262fb8 100644
--- a/src/shred.c
+++ b/src/shred.c
@@ -83,6 +83,7 @@
#include <getopt.h>
#include <stdio.h>
+#include <assert.h>
#include <setjmp.h>
#include <signal.h>
#include <sys/types.h>
@@ -990,13 +991,14 @@ fillpattern (int type, unsigned char *r, size_t size)
}
/*
- * Fill a buffer with random data.
- * size is rounded UP to a multiple of ISAAC_BYTES.
+ * Fill a buffer, R (of size SIZE_MAX), with random data.
+ * SIZE is rounded UP to a multiple of ISAAC_BYTES.
*/
static void
-fillrand (struct isaac_state *s, word32 *r, size_t size)
+fillrand (struct isaac_state *s, word32 *r, size_t size_max, size_t size)
{
size = (size + ISAAC_BYTES - 1) / ISAAC_BYTES;
+ assert (size <= size_max);
while (size--)
{
@@ -1083,12 +1085,14 @@ dopass (int fd, char const *qname, off_t *sizep, int type,
lim = sizeof r;
if ((off_t) lim > size - offset && size != -1)
{
+ if (size < offset)
+ break;
lim = (size_t) (size - offset);
if (!lim)
break;
}
if (type < 0)
- fillrand (s, r, lim);
+ fillrand (s, r, sizeof r, lim);
/* Loop to retry partial writes. */
for (soff = 0; soff < lim; soff += ssize)
{
@@ -1422,17 +1426,33 @@ do_wipefd (int fd, char const *qname, struct isaac_state *s,
size = flags->size;
if (size == -1)
{
- size = (S_ISREG (st.st_mode)
- ? st.st_size
- : lseek (fd, (off_t) 0, SEEK_END));
- if (size < (S_ISREG (st.st_mode) ? 0 : -1))
+ /* Accept a length of zero only if it's a regular file.
+ For any other type of file, try to get the size another way. */
+ if (S_ISREG (st.st_mode))
{
- error (0, 0, _("%s: file has negative size"), qname);
- return -1;
+ size = st.st_size;
+ if (size < 0)
+ {
+ error (0, 0, _("%s: file has negative size"), qname);
+ return -1;
+ }
}
+ else
+ {
+ size = lseek (fd, (off_t) 0, SEEK_END);
+ if (size <= 0)
+ {
+ /* We are unable to determine the length, up front.
+ Let dopass do that as part of its first iteration. */
+ size = -1;
+ }
+ }
+
if (0 <= size && !(flags->exact))
{
size += ST_BLKSIZE (st) - 1 - (size - 1) % ST_BLKSIZE (st);
+
+ /* If in rounding up, we've just overflowed, use the maximum. */
if (size < 0)
size = TYPE_MAXIMUM (off_t);
}