diff options
-rw-r--r-- | src/df.c | 2 | ||||
-rw-r--r-- | src/shred.c | 38 |
2 files changed, 26 insertions, 14 deletions
@@ -1650,6 +1650,8 @@ main (int argc, char **argv) return EXIT_FAILURE; } + assume (0 < optind); + if (optind < argc) { int i; diff --git a/src/shred.c b/src/shred.c index 5bb0d1726..2857835a2 100644 --- a/src/shred.c +++ b/src/shred.c @@ -408,6 +408,14 @@ dorewind (int fd, struct stat const *st) return offset == 0; } +/* By convention, negative sizes represent unknown values. */ + +static bool +known (off_t size) +{ + return 0 <= size; +} + /* * Do pass number K of N, writing *SIZEP bytes of the given pattern TYPE * to the file descriptor FD. K and N are passed in only for verbose @@ -423,9 +431,8 @@ dopass (int fd, struct stat const *st, char const *qname, off_t *sizep, int type, struct randread_source *s, unsigned long int k, unsigned long int n) { - uintmax_t size = MAX (0, *sizep); - bool known_size = 0 <= *sizep; - uintmax_t offset; /* Current file position */ + off_t size = *sizep; + off_t offset; /* Current file posiiton */ time_t thresh IF_LINT ( = 0); /* Time to maybe print next status update */ time_t now = 0; /* Current time */ size_t lim; /* Amount of data to try writing */ @@ -470,7 +477,7 @@ dopass (int fd, struct stat const *st, char const *qname, off_t *sizep, /* Constant fill patterns need only be set up once. */ if (type >= 0) { - lim = (known_size && size < FILLPATTERN_SIZE ? size : FILLPATTERN_SIZE); + lim = known (size) && size < FILLPATTERN_SIZE ? size : FILLPATTERN_SIZE; fillpattern (type, pbuf, lim); passname (pbuf, pass_string); } @@ -492,7 +499,7 @@ dopass (int fd, struct stat const *st, char const *qname, off_t *sizep, { /* How much to write this time? */ lim = output_size; - if (known_size && size - offset < output_size) + if (known (size) && size - offset < output_size) { if (size < offset) break; @@ -506,13 +513,15 @@ dopass (int fd, struct stat const *st, char const *qname, off_t *sizep, for (soff = 0; soff < lim; soff += ssize) { ssize = write (fd, pbuf + soff, lim - soff); - if (ssize <= 0) + if (0 < ssize) + assume (ssize <= lim - soff); + else { - if (! known_size && (ssize == 0 || errno == ENOSPC)) + if (! known (size) && (ssize == 0 || errno == ENOSPC)) { - /* We have found the end of the file */ - *sizep = size = offset + soff; - known_size = true; + /* We have found the end of the file. */ + if (soff <= OFF_T_MAX - offset) + *sizep = size = offset + soff; break; } else @@ -541,7 +550,8 @@ dopass (int fd, struct stat const *st, char const *qname, off_t *sizep, also enables direct I/O on some (file) systems. */ verify (PERIODIC_OUTPUT_SIZE % SECTOR_SIZE == 0); verify (NONPERIODIC_OUTPUT_SIZE % SECTOR_SIZE == 0); - if (errnum == EIO && known_size && (soff | SECTOR_MASK) < lim) + if (errnum == EIO && known (size) + && (soff | SECTOR_MASK) < lim) { size_t soff1 = (soff | SECTOR_MASK) + 1; if (lseek (fd, offset + soff1, SEEK_SET) != -1) @@ -561,7 +571,7 @@ dopass (int fd, struct stat const *st, char const *qname, off_t *sizep, /* Okay, we have written "soff" bytes. */ - if (offset > OFF_T_MAX - (off_t) soff) + if (OFF_T_MAX - offset < soff) { error (0, 0, _("%s: file too large"), qname); other_error = true; @@ -570,7 +580,7 @@ dopass (int fd, struct stat const *st, char const *qname, off_t *sizep, offset += soff; - bool done = (! known_size) || offset == size; + bool done = offset == size; /* Time to print progress? */ if (n && ((done && *previous_human_offset) @@ -586,7 +596,7 @@ dopass (int fd, struct stat const *st, char const *qname, off_t *sizep, if (done || !STREQ (previous_human_offset, human_offset)) { - if (! known_size) + if (! known (size)) error (0, 0, _("%s: pass %lu/%lu (%s)...%s"), qname, k, n, pass_string, human_offset); else |