bug-coreutils
[Top][All Lists]
Advanced

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

PATCH: df -mP alignment fix and -c --total option added to df


From: Dennis Smit
Subject: PATCH: df -mP alignment fix and -c --total option added to df
Date: Fri, 7 Nov 2003 17:49:54 -0500 (EST)

I had a glance at the TODO list and saw that df -mP had an alignment bug
so i fixed that. Also i saw that an --total option was requested so
did that as well.

I hope i did it alright, if not please make me know so that i can
improve my work. Also i would like to do some more work on df or
possibly other things.

ChangeLog:
        * src/df.c (print_header): fixt alignment for `df -mP'.
        (main): added support for -c --total.
        (show_grand_total): added function to show the grand total.
        (show_information): added function splitted this from show_dev
        so the grand_total can use the same entry displaying function.
        (convert_blocksize): added function that converts the blocksize
        for the grandtotal so that only the same blocksize amounts are
        added to each other. Is this function right ? (took from
        human_readable).
        (show_dev): splitted out the show_information part and added
        support for grand total option.

PATCH:
--- df.c        2003-11-07 07:18:30.000000000 +0100
+++ df_new.c    2003-11-07 23:28:24.000000000 +0100
@@ -17,7 +17,8 @@

 /* Written by David MacKenzie <address@hidden>.
    --human-readable and --megabyte options added by address@hidden
-   --si and large file support added by address@hidden  */
+   --si and large file support added by address@hidden
+   --total added by address@hidden */

 #include <config.h>
 #include <stdio.h>
@@ -57,6 +58,9 @@
 /* If nonzero, show only local filesystems.  */
 static int show_local_fs;

+/* If nonzero, show a grand total. */
+static int show_total;
+
 /* If nonzero, output data for each filesystem corresponding to a
    command line argument -- even if it's a dummy (automounter) entry.  */
 static int show_listed_fs;
@@ -111,6 +115,12 @@
 /* If nonzero, print filesystem type as well.  */
 static int print_type;

+/* The following variables are used for generating a total static. */
+static uintmax_t total_total;
+static uintmax_t total_available;
+static uintmax_t total_negate_available;
+static uintmax_t total_available_to_root;
+
 /* For long options that have no equivalent short option, use a
    non-character as a pseudo short option, starting with CHAR_MAX + 1.  */
 enum
@@ -128,6 +138,7 @@
   {"si", no_argument, NULL, 'H'},
   {"kilobytes", no_argument, NULL, 'k'}, /* long form is obsolescent */
   {"local", no_argument, NULL, 'l'},
+  {"total", no_argument, NULL, 'c'},
   {"megabytes", no_argument, NULL, 'm'}, /* obsolescent */
   {"portability", no_argument, NULL, 'P'},
   {"print-type", no_argument, NULL, 'T'},
@@ -160,7 +171,7 @@
        printf (_("     Size   Used  Avail Use%%"));
     }
   else if (posix_format)
-    printf (_(" %4s-blocks      Used Available Capacity"),
+    printf (_(" %3s-blocks   Used Available Capacity"),
            umaxtostr (output_block_size, buf));
   else
     {
@@ -253,62 +264,85 @@
     }
 }

-/* Display a space listing for the disk device with absolute path DISK.
+/* This function is used to convert data from one blocksize to another */
+uintmax_t convert_blocksize (uintmax_t n, uintmax_t from_block_size,
+                            uintmax_t to_block_size)
+{
+  if (from_block_size >= to_block_size &&
+      from_block_size % to_block_size)
+    {
+      uintmax_t multiplier = from_block_size / to_block_size;
+      return n * multiplier;
+    }
+  else if (from_block_size != 0 && to_block_size % from_block_size == 0)
+    {
+      uintmax_t divisor = to_block_size / from_block_size;
+      return n / divisor;
+    }
+  else
+    {
+      /* Either the result cannot be computed easily using uintmax_t,
+        or from_block_size is zero.  Fall back on floating point.
+        This can yield answers that are slightly off.  */
+      return n * (from_block_size / (long double) to_block_size);
+    }
+}
+
+/* This function handles the printing of an filesystem entry.
+   The reason for the split between show_information and
+   show_dev is so that the -c --total option can make use
+   of this function to print it's information like the
+   filesystem entries.
    If MOUNT_POINT is non-NULL, it is the path of the root of the
    filesystem on DISK.
    If FSTYPE is non-NULL, it is the type of the filesystem on DISK.
    If MOUNT_POINT is non-NULL, then DISK may be NULL -- certain systems may
-   not be able to produce statistics in this case.
-   ME_DUMMY and ME_REMOTE are the mount entry flags.  */
+   not be able to produce statistics in this case. */

 static void
-show_dev (const char *disk, const char *mount_point, const char *fstype,
-         int me_dummy, int me_remote)
+show_information (const char *disk, const char *mount_point,
+                 const char *fstype, uintmax_t total,
+                 uintmax_t available, uintmax_t negate_available,
+                 uintmax_t available_to_root,
+                 uintmax_t input_units, uintmax_t output_units)
 {
-  struct fs_usage fsu;
-  const char *stat_file;
   char buf[3][LONGEST_HUMAN_READABLE + 2];
   int width;
   int use_width;
-  uintmax_t input_units;
-  uintmax_t output_units;
-  uintmax_t total;
-  uintmax_t available;
-  int negate_available;
-  uintmax_t available_to_root;
-  uintmax_t used;
-  int negate_used;
+  int negate_used = 0;
+  uintmax_t used = -1;
   double pct = -1;

-  if (me_remote && show_local_fs)
-    return;
-
-  if (me_dummy && show_all_fs == 0 && !show_listed_fs)
-    return;
-
-  if (!selected_fstype (fstype) || excluded_fstype (fstype))
-    return;
+  if (inode_format)
+    {
+      width = 7;
+      use_width = 5;
+    }
+  else
+    {
+      width = (human_output_opts & human_autoscale
+               ? 5 + ! (human_output_opts & human_base_1024)
+              : 9);

-  /* If MOUNT_POINT is NULL, then the filesystem is not mounted, and this
-     program reports on the filesystem that the special file is on.
-     It would be better to report on the unmounted filesystem,
-     but statfs doesn't do that on most systems.  */
-  stat_file = mount_point ? mount_point : disk;
+      use_width = ((posix_format
+                   && ! (human_output_opts & human_autoscale))
+                   ? 8 : 4);
+    }

-  if (get_fs_usage (stat_file, disk, &fsu))
+  if (total != -1 && available_to_root != -1)
     {
-      error (0, errno, "%s", quote (stat_file));
-      exit_status = 1;
-      return;
+      used = total - available_to_root;
+      if (total < available_to_root)
+       {
+         negate_used = 1;
+         used = - used;
+       }
     }

-  if (fsu.fsu_blocks == 0 && !show_all_fs && !show_listed_fs)
-    return;
-
   if (! disk)
-    disk = "-";                        /* unknown */
+    disk = "-";                 /* unknown */
   if (! fstype)
-    fstype = "-";              /* unknown */
+    fstype = "-";               /* unknown */

   /* df.c reserved 5 positions for fstype,
      but that does not suffice for type iso9660 */
@@ -316,6 +350,7 @@
     {
       int disk_name_len = (int) strlen (disk);
       int fstype_len = (int) strlen (fstype);
+
       if (disk_name_len + fstype_len + 2 < 20)
        printf ("%s%*s  ", disk, 18 - disk_name_len, fstype);
       else if (!posix_format)
@@ -331,46 +366,8 @@
        printf ("%-20s", disk);
     }

-  if (inode_format)
-    {
-      width = 7;
-      use_width = 5;
-      input_units = output_units = 1;
-      total = fsu.fsu_files;
-      available = fsu.fsu_ffree;
-      negate_available = 0;
-      available_to_root = available;
-    }
-  else
-    {
-      width = (human_output_opts & human_autoscale
-              ? 5 + ! (human_output_opts & human_base_1024)
-              : 9);
-      use_width = ((posix_format
-                   && ! (human_output_opts & human_autoscale))
-                  ? 8 : 4);
-      input_units = fsu.fsu_blocksize;
-      output_units = output_block_size;
-      total = fsu.fsu_blocks;
-      available = fsu.fsu_bavail;
-      negate_available = fsu.fsu_bavail_top_bit_set;
-      available_to_root = fsu.fsu_bfree;
-    }
-
-  used = -1;
-  negate_used = 0;
-  if (total != -1 && available_to_root != -1)
-    {
-      used = total - available_to_root;
-      if (total < available_to_root)
-       {
-         negate_used = 1;
-         used = - used;
-       }
-    }
-
   printf (" %*s %*s %*s ",
-         width, df_readable (0, total,
+          width, df_readable (0, total,
                              buf[0], input_units, output_units),
          width, df_readable (negate_used, used,
                              buf[1], input_units, output_units),
@@ -391,13 +388,14 @@
   else
     {
       /* The calculation cannot be done easily with integer
-        arithmetic.  Fall back on floating point.  This can suffer
-        from minor rounding errors, but doing it exactly requires
-        multiple precision arithmetic, and it's not worth the
-        aggravation.  */
+         arithmetic.  Fall back on floating point.  This can suffer
+         from minor rounding errors, but doing it exactly requires
+         multiple precision arithmetic, and it's not worth the
+         aggravation.  */
       double u = negate_used ? - (double) - used : used;
       double a = negate_available ? - (double) - available : available;
       double nonroot_total = u + a;
+
       if (nonroot_total)
        {
          double ipct;
@@ -406,8 +404,9 @@

          /* Like `pct = ceil (dpct);', but avoid ceil so that
             the math library needn't be linked.  */
+
          if (ipct - 1 < pct && pct <= ipct + 1)
-           pct = ipct + (ipct < pct);
+             pct = ipct + (ipct < pct);
        }
     }

@@ -415,13 +414,12 @@
     printf ("%*.0f%%", use_width - 1, pct);
   else
     printf ("%*s", use_width, "- ");
-
   if (mount_point)
     {
 #ifdef HIDE_AUTOMOUNT_PREFIX
       /* Don't print the first directory name in MOUNT_POINT if it's an
-        artifact of an automounter.  This is a bit too aggressive to be
-        the default.  */
+         artifact of an automounter.  This is a bit too aggressive to be
+         the default.  */
       if (strncmp ("/auto/", mount_point, 6) == 0)
        mount_point += 5;
       else if (strncmp ("/tmp_mnt/", mount_point, 9) == 0)
@@ -432,6 +430,81 @@
   putchar ('\n');
 }

+/* Prepares an filesystem entry for the show_information function and also
+   does the stuff for the grand total static */
+
+static void
+show_dev (const char *disk, const char *mount_point, const char *fstype,
+         int me_dummy, int me_remote)
+{
+  struct fs_usage fsu;
+  const char *stat_file;
+  uintmax_t input_units;
+  uintmax_t total;
+  uintmax_t available;
+  uintmax_t negate_available;
+  uintmax_t available_to_root;
+
+  if (me_remote && show_local_fs)
+    return;
+
+  if (me_dummy && show_all_fs == 0 && !show_listed_fs)
+    return;
+
+  if (!selected_fstype (fstype) || excluded_fstype (fstype))
+    return;
+
+  /* If MOUNT_POINT is NULL, then the filesystem is not mounted, and this
+     program reports on the filesystem that the special file is on.
+     It would be better to report on the unmounted filesystem,
+     but statfs doesn't do that on most systems.  */
+  stat_file = mount_point ? mount_point : disk;
+
+  if (get_fs_usage (stat_file, disk, &fsu))
+    {
+      error (0, errno, "%s", quote (stat_file));
+      exit_status = 1;
+      return;
+    }
+
+  if (fsu.fsu_blocks == 0 && !show_all_fs && !show_listed_fs)
+    return;
+
+  if (inode_format)
+    {
+      total = fsu.fsu_files;
+      available = fsu.fsu_ffree;
+      negate_available = 0;
+      available_to_root = available;
+      input_units = 1;
+    }
+  else
+    {
+      input_units = fsu.fsu_blocksize;
+      total = fsu.fsu_blocks;
+      available = fsu.fsu_bavail;
+      negate_available = fsu.fsu_bavail_top_bit_set;
+      available_to_root = fsu.fsu_bfree;
+    }
+
+  /* Show entry information. */
+  show_information (disk, mount_point, fstype, total,
+                   available, negate_available, available_to_root,
+                   input_units, output_block_size);
+
+  /* Convert blocksize to output_block_size so that no different blocksized
+     entries are added to each other. */
+  total_total += convert_blocksize (total, input_units, output_block_size);
+  total_available += convert_blocksize (available, input_units,
+                                       output_block_size);
+  total_negate_available += convert_blocksize (negate_available,
+                                              input_units,
+                                              output_block_size);
+  total_available_to_root += convert_blocksize (available_to_root,
+                                               input_units,
+                                               output_block_size);
+}
+
 /* Return the root mountpoint of the filesystem on which FILE exists, in
    malloced storage.  FILE_STAT should be the result of stating FILE.
    Give a diagnostic and return NULL if unable to determine the mount point.
@@ -690,6 +763,17 @@
              me->me_dummy, me->me_remote);
 }

+/* Show a grand total statics. */
+
+static void
+show_grand_total (void)
+{
+  show_information ("total", NULL, NULL, total_total,
+                   total_available, total_negate_available,
+                   total_available_to_root,
+                   output_block_size, output_block_size);
+}
+
 /* Add FSTYPE to the list of filesystem types to display. */

 static void
@@ -743,6 +827,7 @@
   -i, --inodes          list inode information instead of block usage\n\
   -k                    like --block-size=1K\n\
   -l, --local           limit listing to local filesystems\n\
+  -c, --total           produce a grand total\n\
       --no-sync         do not invoke sync before getting usage info 
(default)\n\
 "), stdout);
       fputs (_("\
@@ -792,7 +877,7 @@
   posix_format = 0;
   exit_status = 0;

-  while ((c = getopt_long (argc, argv, "aB:iF:hHklmPTt:vx:", long_options, 
NULL))
+  while ((c = getopt_long (argc, argv, "aB:icF:hHklmPTt:vx:", long_options, 
NULL))
         != -1)
     {
       switch (c)
@@ -823,6 +908,9 @@
        case 'l':
          show_local_fs = 1;
          break;
+       case 'c':
+         show_total = 1;
+         break;
        case 'm': /* obsolescent */
          human_output_opts = 0;
          output_block_size = 1024 * 1024;
@@ -926,6 +1014,9 @@
   if (require_sync)
     sync ();

+  if (inode_format)
+    output_block_size = 1;
+
   if (optind < argc)
     {
       int i;
@@ -945,6 +1036,9 @@
       print_header ();
       show_all_entries ();
     }
-
+
+  if (show_total)
+    show_grand_total ();
+
   exit (exit_status);
 }





reply via email to

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