Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 29 Nov 1999 21:39:53 -0800
From:      Chris Piazza <cpiazza@jaxon.net>
To:        matt@csis.gvsu.edu
Cc:        freebsd-hackers@FreeBSD.ORG
Subject:   Re: Human readable df
Message-ID:  <19991129213953.D16943@norn.ca.eu.org>
In-Reply-To: <19991129230436.A6501@badmofo>; from matt@csis.gvsu.edu on Mon, Nov 29, 1999 at 11:04:36PM -0500
References:  <19991129230436.A6501@badmofo>

next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, Nov 29, 1999 at 11:04:36PM -0500, matt@csis.gvsu.edu wrote:
> Not sure if -hackers is the place for this, but here goes.
> 
> Here's a patch to add -h flag to df to produce human readable
> output. This makes it easier to read if the disk is big.
> Example:
> 
> [badmofo@/home/matt] df -h
> Filesystem    Size   Used    Avail Capacity Mounted on
> /dev/wd0s1a   722M    20M   644M     3%     /
> /dev/wd0s2h   9.9G   4.4G   4.8G    48%     /usr
> procfs        4.0K   4.0K     0B   100%     /proc
> ....
> 
> Code merged from OpenBSD and added to FreeBSD-STABLE. 

[patch snipped]

For what it's worth, I'd ported this a few months back (file dated
Aug 28), but forgot about it :-).  Here's the patch updated for
-current, anyway.

Index: df.1
===================================================================
RCS file: /home/ncvs/src/bin/df/df.1,v
retrieving revision 1.17
diff -u -r1.17 df.1
--- df.1	1999/11/01 04:57:42	1.17
+++ df.1	1999/11/30 05:38:47
@@ -40,7 +40,7 @@
 .Nd display free disk space
 .Sh SYNOPSIS
 .Nm df
-.Op Fl aikn
+.Op Fl ahikmn
 .Op Fl t Ar type
 .Op Ar file | Ar filesystem ...
 .Sh DESCRIPTION
@@ -62,6 +62,10 @@
 .It Fl a
 Show all mount points, including those that were mounted with the MNT_IGNORE
 flag.
+.It Fl h
+"Human-readable" output.  Use unit suffixes: Byte, Kilobyte, Megabyte,
+Gigabyte, Terabyte, Petabyte, Exabyte in order to reduce the number of
+digits to four or less.
 .It Fl i
 Include statistics on the number of free inodes.
 .It Fl k
Index: df.c
===================================================================
RCS file: /home/ncvs/src/bin/df/df.c,v
retrieving revision 1.22
diff -u -r1.22 df.c
--- df.c	1999/11/01 04:57:43	1.22
+++ df.c	1999/11/30 05:38:47
@@ -59,21 +59,27 @@
 #include <err.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <math.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 
+typedef enum { NONE = 0, KILO, MEGA, GIGA, TERA, PETA /* , EXA */ } unit_t;
+
 int	  checkvfsname __P((const char *, char **));
 char	**makevfslist __P((char *));
 long	  regetmntinfo __P((struct statfs **, long, char **));
 int	  bread __P((off_t, void *, int));
 char	 *getmntpt __P((char *));
+void	  prthuman __P((struct statfs *, long));
+void	  prthumanval __P((double)); 
 void	  prtstat __P((struct statfs *, int));
 int	  ufs_df __P((char *, int));
+unit_t	  unit_adjust __P((double *));
 void	  usage __P((void));
 
-int	aflag = 0, iflag, nflag;
+int	aflag = 0, hflag, iflag, nflag;
 struct	ufs_args mdev;
 
 int
@@ -88,11 +94,14 @@
 	char *mntpt, *mntpath, **vfslist;
 
 	vfslist = NULL;
-	while ((ch = getopt(argc, argv, "aiknt:")) != -1)
+	while ((ch = getopt(argc, argv, "ahiknt:")) != -1)
 		switch (ch) {
 		case 'a':
 			aflag = 1;
 			break;
+		case 'h':
+			hflag = 1;
+			break;
 		case 'i':
 			iflag = 1;
 			break;
@@ -249,6 +258,68 @@
 }
 
 /*
+ * Output in "human-readable" format.  Uses 3 digits max and puts
+ * unit suffixes at the end.  Makes output compact and easy to read,
+ * especially on huge disks.
+ *
+ */
+
+unit_t
+unit_adjust(val)
+	double *val;
+{
+	double abval;
+	unit_t unit;
+
+	abval = fabs(*val);
+	if (abval < 1024)
+		unit = NONE;
+	else if (abval < 1048576ULL) {
+		unit = KILO;
+		*val /= 1024;
+	} else if (abval < 1073741824ULL) {
+		unit = MEGA;
+		*val /= 1048576;
+	} else if (abval < 1099511627776ULL) {
+		unit = GIGA;
+		*val /= 1073741824ULL;
+	} else if (abval < 1125899906842624ULL) {
+		unit = TERA;
+		*val /= 1099511627776ULL;
+	} else if (abval < 1152921504606846976ULL) {
+		unit = PETA;
+		*val /= 1125899906842624ULL;
+	}
+	return (unit);
+}
+
+void
+prthuman(sfsp, used)
+	struct statfs *sfsp;
+	long used; 
+{
+	prthumanval((double)(sfsp->f_blocks) * (double)(sfsp->f_bsize));
+	prthumanval((double)(used) * (double)(sfsp->f_bsize));
+	prthumanval((double)(sfsp->f_bavail) * (double)(sfsp->f_bsize));
+}
+
+void
+prthumanval(bytes)
+	double bytes;
+{
+	unit_t unit;
+
+	unit = unit_adjust(&bytes);
+
+	if (bytes == 0)
+		(void)printf("     0B");
+	else if (bytes > 10)
+		(void)printf(" %5.0f%c", bytes, "BKMGTPE"[unit]);
+	else
+		(void)printf(" %5.1f%c", bytes, "BKMGTPE"[unit]);
+}
+
+/*
  * Convert statfs returned filesystem size into BLOCKSIZE units.
  * Attempts to avoid overflow for large filesystems.
  */
@@ -272,9 +343,16 @@
 	if (maxwidth < 11)
 		maxwidth = 11;
 	if (++timesthrough == 1) {
-		header = getbsize(&headerlen, &blocksize);
-		(void)printf("%-*.*s %s     Used    Avail Capacity",
-		    maxwidth, maxwidth, "Filesystem", header);
+		if (hflag) {
+			header = "  Size";
+			headerlen = strlen(header);
+			(void)printf("%-*.*s %s   Used  Avail Capacity",
+			    maxwidth, maxwidth, "Filesystem", header);
+		} else {
+			header = getbsize(&headerlen, &blocksize);
+			(void)printf("%-*.*s %s     Used    Avail Capacity",
+			    maxwidth, maxwidth, "Filesystem", header);
+		}
 		if (iflag)
 			(void)printf(" iused   ifree  %%iused");
 		(void)printf("  Mounted on\n");
@@ -282,10 +360,13 @@
 	(void)printf("%-*.*s", maxwidth, maxwidth, sfsp->f_mntfromname);
 	used = sfsp->f_blocks - sfsp->f_bfree;
 	availblks = sfsp->f_bavail + used;
-	(void)printf(" %*ld %8ld %8ld", headerlen,
-	    fsbtoblk(sfsp->f_blocks, sfsp->f_bsize, blocksize),
-	    fsbtoblk(used, sfsp->f_bsize, blocksize),
-	    fsbtoblk(sfsp->f_bavail, sfsp->f_bsize, blocksize));
+	if (hflag)
+		prthuman(sfsp, used);
+	else
+		(void)printf(" %*ld %8ld %8ld", headerlen,
+	    	    fsbtoblk(sfsp->f_blocks, sfsp->f_bsize, blocksize),
+	    	    fsbtoblk(used, sfsp->f_bsize, blocksize),
+	    	    fsbtoblk(sfsp->f_bavail, sfsp->f_bsize, blocksize));
 	(void)printf(" %5.0f%%",
 	    availblks == 0 ? 100.0 : (double)used / (double)availblks * 100.0);
 	if (iflag) {

-Chris
-- 
cpiazza@jaxon.net   cpiazza@FreeBSD.org
        Abbotsford, BC, Canada


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19991129213953.D16943>