bug-coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] df: Fix bug when totaling unknown values.


From: Paul Eggert
Subject: Re: [PATCH] df: Fix bug when totaling unknown values.
Date: Wed, 25 Mar 2009 21:33:44 -0700
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.3 (gnu/linux)

Jim Meyering <address@hidden> writes:

> So how about a function like summable (uintmax_t val) to be used
> in place of each of those 5 tests?

Sure thing, though I count 11 tests total, not just the 5 in the
previous patch.  I prefer a name like 'known_value' to 'summable', as
it's a bit more specific.  Here's that same patch, followed by a further
patch to add known_value, generated by git-format-patch.

=======

>From abc8e21a0b5a55bed938b30adf217a26c1a17bac Mon Sep 17 00:00:00 2001
From: Paul Eggert <address@hidden>
Date: Wed, 25 Mar 2009 14:16:46 -0700
Subject: [PATCH] df: Fix bug when totaling unknown values.

* src/df.c (show_dev): Don't add UINTMAX_MAX to grand totals, as that
value indicates that the true value is unknown; adding it effectively
subtracts 1 from the total, whereas we want to leave the total alone.
---
 src/df.c |   19 ++++++++++++-------
 1 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/src/df.c b/src/df.c
index 0bb3b1e..bb24934 100644
--- a/src/df.c
+++ b/src/df.c
@@ -393,8 +393,10 @@ show_dev (char const *disk, char const *mount_point,
       negate_available = false;
       available_to_root = available;
 
-      grand_fsu.fsu_files += total;
-      grand_fsu.fsu_ffree += available;
+      if (total != UINTMAX_MAX)
+       grand_fsu.fsu_files += total;
+      if (available != UINTMAX_MAX)
+       grand_fsu.fsu_ffree += available;
     }
   else
     {
@@ -422,11 +424,14 @@ show_dev (char const *disk, char const *mount_point,
                          & (available != UINTMAX_MAX));
       available_to_root = fsu.fsu_bfree;
 
-      grand_fsu.fsu_blocks += input_units * total;
-      grand_fsu.fsu_bfree  += input_units * available_to_root;
-      add_uint_with_neg_flag (&grand_fsu.fsu_bavail,
-                             &grand_fsu.fsu_bavail_top_bit_set,
-                             input_units * available, negate_available);
+      if (total != UINTMAX_MAX)
+       grand_fsu.fsu_blocks += input_units * total;
+      if (available_to_root != UINTMAX_MAX)
+       grand_fsu.fsu_bfree  += input_units * available_to_root;
+      if (available != UINTMAX_MAX)
+       add_uint_with_neg_flag (&grand_fsu.fsu_bavail,
+                               &grand_fsu.fsu_bavail_top_bit_set,
+                               input_units * available, negate_available);
     }
 
   used = UINTMAX_MAX;
-- 
1.5.3.2


>From 2c35010ca7651251376f113983141d08b6ecce0a Mon Sep 17 00:00:00 2001
From: Paul Eggert <address@hidden>
Date: Wed, 25 Mar 2009 20:50:17 -0700
Subject: [PATCH] df: Port the known-value fix to AIX as well.

* src/df.c (known_value): New function, which also works on AIX file systems.
(df_readable, show_dev): Use it instead of hardcoding comparison to
UINTMAX_MAX.  Suggested by Jim Meyering and Matthew Woehlke.
---
 src/df.c |   30 ++++++++++++++++++++----------
 1 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/src/df.c b/src/df.c
index bb24934..bbbb47d 100644
--- a/src/df.c
+++ b/src/df.c
@@ -231,18 +231,28 @@ excluded_fstype (const char *fstype)
   return false;
 }
 
+/* Return true if N is a known integer value.  On many file systems,
+   UINTMAX_MAX represents an unknown value; on AIX, UINTMAX_MAX - 1
+   represents unknown.  Use a rule that works on AIX file systems, and
+   that almost-always works on other types.  */
+static bool
+known_value (uintmax_t n)
+{
+  return n < UINTMAX_MAX - 1;
+}
+
 /* Like human_readable (N, BUF, human_output_opts, INPUT_UNITS, OUTPUT_UNITS),
    except:
 
     - If NEGATIVE, then N represents a negative number,
       expressed in two's complement.
-    - Otherwise, return "-" if N is UINTMAX_MAX.  */
+    - Otherwise, return "-" if N is unknown.  */
 
 static char const *
 df_readable (bool negative, uintmax_t n, char *buf,
             uintmax_t input_units, uintmax_t output_units)
 {
-  if (n == UINTMAX_MAX && !negative)
+  if (! known_value (n) && !negative)
     return "-";
   else
     {
@@ -393,9 +403,9 @@ show_dev (char const *disk, char const *mount_point,
       negate_available = false;
       available_to_root = available;
 
-      if (total != UINTMAX_MAX)
+      if (known_value (total))
        grand_fsu.fsu_files += total;
-      if (available != UINTMAX_MAX)
+      if (known_value (available))
        grand_fsu.fsu_ffree += available;
     }
   else
@@ -421,14 +431,14 @@ show_dev (char const *disk, char const *mount_point,
       total = fsu.fsu_blocks;
       available = fsu.fsu_bavail;
       negate_available = (fsu.fsu_bavail_top_bit_set
-                         & (available != UINTMAX_MAX));
+                         & known_value (available));
       available_to_root = fsu.fsu_bfree;
 
-      if (total != UINTMAX_MAX)
+      if (known_value (total))
        grand_fsu.fsu_blocks += input_units * total;
-      if (available_to_root != UINTMAX_MAX)
+      if (known_value (available_to_root))
        grand_fsu.fsu_bfree  += input_units * available_to_root;
-      if (available != UINTMAX_MAX)
+      if (known_value (available))
        add_uint_with_neg_flag (&grand_fsu.fsu_bavail,
                                &grand_fsu.fsu_bavail_top_bit_set,
                                input_units * available, negate_available);
@@ -436,7 +446,7 @@ show_dev (char const *disk, char const *mount_point,
 
   used = UINTMAX_MAX;
   negate_used = false;
-  if (total != UINTMAX_MAX && available_to_root != UINTMAX_MAX)
+  if (known_value (total) && known_value (available_to_root))
     {
       used = total - available_to_root;
       negate_used = (total < available_to_root);
@@ -451,7 +461,7 @@ show_dev (char const *disk, char const *mount_point,
          width, df_readable (negate_available, available,
                              buf[2], input_units, output_units));
 
-  if (used == UINTMAX_MAX || available == UINTMAX_MAX)
+  if (! known_value (used) || ! known_value (available))
     ;
   else if (!negate_used
           && used <= TYPE_MAXIMUM (uintmax_t) / 100
-- 
1.5.3.2





reply via email to

[Prev in Thread] Current Thread [Next in Thread]