Subject: Re: Suggestion for changes to df(1) and du(1)
To: Tomas Svensson <tsn@gbdev.net>
From: Klaus Klein <kleink@reziprozitaet.de>
List: tech-userlevel
Date: 11/19/2001 11:48:09
Tomas Svensson <tsn@gbdev.net> writes:
> Does anyone have an opinion about adding the flag -h to df(1) and du(1)?
> It would be to print the statistics in a more "human-readable" and
> compact style.
>
> Example output:
>
> Filesystem Size Used Avail Capacity Mounted on
> /dev/wd0a 97M 31M 61M 33% /
> /dev/wd0e 97M 4.7M 88M 5% /var
> /dev/wd0g 2.8G 1.5G 1.2G 54% /usr
> /dev/wd0f 97M 1.0K 92M 0% /tmp
> /dev/wd0h 1.8G 297M 1.4G 17% /home
> /dev/fd0a 1.4M 636K 787K 44% /mnt
>
> FreeBSD/OpenBSD and GNU fileutils support this flag already, but does
> anyone know if this flag would violate POSIX or SUS?
It's not currently defined by those specifications, so documenting it
as another extension would be fine. Same for -g.
(OTOH, several file-related utilities are using -h to specify a
do-not-follow-symlink behaviour; it's arguable whether it'd be useful
or not for df(1), and it'd be sensible to choose another option letter
for human-readable style.)
> --- df1/df.c Sun Nov 18 23:08:29 2001
> +++ df/df.c Sun Nov 18 17:59:27 2001
> @@ -62,6 +62,7 @@
> #include <err.h>
> #include <errno.h>
> #include <fcntl.h>
> +#include <math.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
Actually, why are you using FP arithmetic here? intmax_t ought to be
fine for this purpose, I think.
> @@ -92,11 +94,17 @@
> int ch, i, maxwidth, width;
> char *mntpt;
>
> - while ((ch = getopt(argc, argv, "aiklmnPt:")) != -1)
> + while ((ch = getopt(argc, argv, "aghiklmnPt:")) != -1)
> switch (ch) {
> case 'a':
> aflag = 1;
> break;
> + case 'g':
> + gflag = 1;
> + break;
> + case 'h':
> + hflag = 1;
> + break;
> case 'i':
> iflag = 1;
> break;
If the -P option is encountered after the -h option, the latter's flag
should be cleared again since it's ... quite incompatble. :-)
> @@ -326,6 +334,41 @@
> (num) / ((bs) / (fsbs)) : (num) * ((fsbs) / (bs)))
>
> /*
> + * Print sizes in a more human-readable and compact form.
> + */
> +void
> +prthuman(double bytes)
> +{
> + double abytes;
> + char unit;
> +
> + if (bytes == 0)
> + (void)printf(" 0B");
> + else {
> + abytes = fabs(bytes);
> + if (abytes < 1024)
> + unit = 'B';
> + else if (abytes < 1024 * 1024ULL) {
> + unit = 'K';
> + bytes /= 1024;
> + } else if (abytes < 1024 * 1024 * 1024ULL) {
> + unit = 'M';
> + bytes /= 1024 * 1024;
> + } else if (abytes < 1024 * 1024 * 1024 * 1024ULL) {
> + unit = 'G';
> + bytes /= 1024 * 1024 * 1024ULL;
> + } else {
> + unit = 'T';
> + bytes /= 1024 * 1024 * 1024 * 1024ULL;
> + }
> + if (bytes > 10)
> + (void)printf(" %5.0f%c", bytes, unit);
> + else
> + (void)printf(" %5.1f%c", bytes, unit);
> + }
> +}
> +
> +/*
> * Print out status about a filesystem.
> */
> void
Hardcoding the decial point symbol is bad practice i18n-wise; I'd
suggest using localeconv()->decimal_point (and setlocale(LC_ALL, "")
in main()).
Other than those, the change looks Ok to me.
- Klaus