[Top][All Lists]
[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);
}
- PATCH: df -mP alignment fix and -c --total option added to df,
Dennis Smit <=