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