diff options
author | Jim Meyering <jim@meyering.net> | 2000-10-28 11:49:52 +0000 |
---|---|---|
committer | Jim Meyering <jim@meyering.net> | 2000-10-28 11:49:52 +0000 |
commit | 37c05b6267140d4afd11ad96cc244e8cd851083c (patch) | |
tree | 23cdfaa3c63b83eb03d1e29ec86f56ac71d904f6 /src | |
parent | 37bcdce62a583c352176d09d7d2d5f7fd2149ae7 (diff) | |
download | coreutils-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')
-rw-r--r-- | src/shred.c | 40 |
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); } |