]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
build: Pacify GCC 5 on 32-bit hosts
authorPaul Eggert <eggert@cs.ucla.edu>
Sat, 3 Oct 2015 07:24:43 +0000 (00:24 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Sat, 3 Oct 2015 07:32:34 +0000 (00:32 -0700)
This pacifies GCC 5 in a better way, without disabling diagnostics.
* src/df.c (main): Tell compiler that optind is positive.
* src/shred.c (known): New function.
(dopass): Go back to off_t for file sizes.
Avoid integer overflow if we run off the end of the file.
Tell compiler that a write cannot write more bytes than requested.

src/df.c
src/shred.c

index 17a2de43706168f365a9743af5f3d34fb5e0d95c..507a0f7343f16f0273f205c327a811c8a78fd3ea 100644 (file)
--- a/src/df.c
+++ b/src/df.c
@@ -1650,6 +1650,8 @@ main (int argc, char **argv)
       return EXIT_FAILURE;
   }
 
+  assume (0 < optind);
+
   if (optind < argc)
     {
       int i;
index 5bb0d1726edc5b49bf80a8adc3e2f7a629af6add..2857835a22be5351bbc8955bd13a8b0ba78a4a8e 100644 (file)
@@ -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