summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPádraig Brady <P@draigBrady.com>2015-10-02 20:28:37 +0100
committerPádraig Brady <P@draigBrady.com>2015-10-03 02:54:51 +0100
commit00ac17889345fe48f6fa4eb2e9457319199e0fe2 (patch)
tree737279b404ea6aee773a2a5ea5578b59e01ca3a0
parent8fe6f70f35ced8ee52c60f1c9f78fb418d723581 (diff)
downloadcoreutils-00ac17889345fe48f6fa4eb2e9457319199e0fe2.tar.xz
build: avoid -Wstrict-overflow warnings with GCC 5.1 on 32 bit
* src/shred.c (dopass): With -O2, GCC 5.1 gives "assuming signed overflow does not occur when simplifying conditional to constant" warnings, in regard to the signed (off_t) variables. Therefore use unsigned (uintmax_t) instead, and a separate boolean to cater for the special meaning of the negative part of the integer range. Noticed at http://hydra.nixos.org/build/24983447
-rw-r--r--src/shred.c20
1 files changed, 11 insertions, 9 deletions
diff --git a/src/shred.c b/src/shred.c
index 195b5d2eb..5bb0d1726 100644
--- a/src/shred.c
+++ b/src/shred.c
@@ -423,8 +423,9 @@ 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)
{
- off_t size = *sizep;
- off_t offset; /* Current file posiiton */
+ uintmax_t size = MAX (0, *sizep);
+ bool known_size = 0 <= *sizep;
+ uintmax_t offset; /* Current file position */
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 */
@@ -469,7 +470,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 = (0 <= size && size < FILLPATTERN_SIZE ? size : FILLPATTERN_SIZE);
+ lim = (known_size && size < FILLPATTERN_SIZE ? size : FILLPATTERN_SIZE);
fillpattern (type, pbuf, lim);
passname (pbuf, pass_string);
}
@@ -491,7 +492,7 @@ dopass (int fd, struct stat const *st, char const *qname, off_t *sizep,
{
/* How much to write this time? */
lim = output_size;
- if (0 <= size && size - offset < output_size)
+ if (known_size && size - offset < output_size)
{
if (size < offset)
break;
@@ -507,10 +508,11 @@ dopass (int fd, struct stat const *st, char const *qname, off_t *sizep,
ssize = write (fd, pbuf + soff, lim - soff);
if (ssize <= 0)
{
- if (size < 0 && (ssize == 0 || errno == ENOSPC))
+ if (! known_size && (ssize == 0 || errno == ENOSPC))
{
- /* Ah, we have found the end of the file */
+ /* We have found the end of the file */
*sizep = size = offset + soff;
+ known_size = true;
break;
}
else
@@ -539,7 +541,7 @@ 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 && 0 <= 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)
@@ -568,7 +570,7 @@ dopass (int fd, struct stat const *st, char const *qname, off_t *sizep,
offset += soff;
- bool done = offset == size;
+ bool done = (! known_size) || offset == size;
/* Time to print progress? */
if (n && ((done && *previous_human_offset)
@@ -584,7 +586,7 @@ dopass (int fd, struct stat const *st, char const *qname, off_t *sizep,
if (done || !STREQ (previous_human_offset, human_offset))
{
- if (size < 0)
+ if (! known_size)
error (0, 0, _("%s: pass %lu/%lu (%s)...%s"),
qname, k, n, pass_string, human_offset);
else