summaryrefslogtreecommitdiffstats
path: root/bin/df/df.c
diff options
context:
space:
mode:
authormharo <mharo@FreeBSD.org>1999-12-15 03:44:09 +0000
committermharo <mharo@FreeBSD.org>1999-12-15 03:44:09 +0000
commita67c7a1db7086ddd78f652b334cd7aa4685f8cb7 (patch)
tree6dbd0f72c5b94da43e862fa1edcd5f2237d83120 /bin/df/df.c
parent61075c3a9d51733f793eca73ba53662a45fe627b (diff)
downloadFreeBSD-src-a67c7a1db7086ddd78f652b334cd7aa4685f8cb7.zip
FreeBSD-src-a67c7a1db7086ddd78f652b334cd7aa4685f8cb7.tar.gz
add human readable output (-h and -H)
Obtained from: parts of human readable code from OpenBSD Reviewed by: obrien add POSIX, byte and megabyte block size ouput flags PR: 13579 (POSIX flag) Submitted by: Mike Meyer <mwm@phone.net>
Diffstat (limited to 'bin/df/df.c')
-rw-r--r--bin/df/df.c142
1 files changed, 131 insertions, 11 deletions
diff --git a/bin/df/df.c b/bin/df/df.c
index ebe9d84..f75b468 100644
--- a/bin/df/df.c
+++ b/bin/df/df.c
@@ -59,21 +59,55 @@ static const char rcsid[] =
#include <err.h>
#include <errno.h>
#include <fcntl.h>
+#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sysexits.h>
#include <unistd.h>
+#define UNITS_SI 1
+#define UNITS_2 2
+
+#define KILO_SZ(n) (n)
+#define MEGA_SZ(n) ((n) * (n))
+#define GIGA_SZ(n) ((n) * (n) * (n))
+#define TERA_SZ(n) ((n) * (n) * (n) * (n))
+#define PETA_SZ(n) ((n) * (n) * (n) * (n) * (n))
+
+#define KILO_2_SZ (KILO_SZ(1024ULL))
+#define MEGA_2_SZ (MEGA_SZ(1024ULL))
+#define GIGA_2_SZ (GIGA_SZ(1024ULL))
+#define TERA_2_SZ (TERA_SZ(1024ULL))
+#define PETA_2_SZ (PETA_SZ(1024ULL))
+
+#define KILO_SI_SZ (KILO_SZ(1000ULL))
+#define MEGA_SI_SZ (MEGA_SZ(1000ULL))
+#define GIGA_SI_SZ (GIGA_SZ(1000ULL))
+#define TERA_SI_SZ (TERA_SZ(1000ULL))
+#define PETA_SI_SZ (PETA_SZ(1000ULL))
+
+unsigned long long vals_si [] = {1, KILO_SI_SZ, MEGA_SI_SZ, GIGA_SI_SZ, TERA_SI_SZ, PETA_SI_SZ};
+unsigned long long vals_base2[] = {1, KILO_2_SZ, MEGA_2_SZ, GIGA_2_SZ, TERA_2_SZ, PETA_2_SZ};
+unsigned long long *valp;
+
+typedef enum { NONE, KILO, MEGA, GIGA, TERA, PETA, UNIT_MAX } unit_t;
+
+int unitp [] = { NONE, KILO, MEGA, GIGA, TERA, PETA };
+
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,16 +122,35 @@ main(argc, argv)
char *mntpt, *mntpath, **vfslist;
vfslist = NULL;
- while ((ch = getopt(argc, argv, "aiknt:")) != -1)
+ while ((ch = getopt(argc, argv, "abHhikmnPt:")) != -1)
switch (ch) {
case 'a':
aflag = 1;
break;
+ case 'b':
+ /* FALLTHROUGH */
+ case 'P':
+ putenv("BLOCKSIZE=512");
+ hflag = 0;
+ break;
+ case 'H':
+ hflag = UNITS_SI;
+ valp = vals_si;
+ break;
+ case 'h':
+ hflag = UNITS_2;
+ valp = vals_base2;
+ break;
case 'i':
iflag = 1;
break;
case 'k':
putenv("BLOCKSIZE=1k");
+ hflag = 0;
+ break;
+ case 'm':
+ putenv("BLOCKSIZE=1m");
+ hflag = 0;
break;
case 'n':
nflag = 1;
@@ -249,6 +302,61 @@ regetmntinfo(mntbufp, mntsize, vfslist)
}
/*
+ * 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;
+ unsigned int unit_sz;
+
+ abval = fabs(*val);
+
+ unit_sz = abval ? ilogb(abval) / 10 : 0;
+
+ if (unit_sz >= UNIT_MAX) {
+ unit = NONE;
+ } else {
+ unit = unitp[unit_sz];
+ *val /= (double)valp[unit_sz];
+ }
+
+ 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 +380,16 @@ prtstat(sfsp, maxwidth)
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 +397,14 @@ prtstat(sfsp, maxwidth)
(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) {
@@ -381,7 +500,8 @@ bread(off, buf, cnt)
void
usage()
{
+
(void)fprintf(stderr,
- "usage: df [-aikn] [-t type] [file | filesystem ...]\n");
- exit(1);
+ "usage: df [-b | -H | -h | -k | -m | -P] [-ain] [-t type] [file | filesystem ...]\n");
+ exit(EX_USAGE);
}
OpenPOWER on IntegriCloud