summaryrefslogtreecommitdiff
path: root/usr.bin/du/du.c
diff options
context:
space:
mode:
authorPaul Janzen <pjanzen@cvs.openbsd.org>2001-02-23 19:14:22 +0000
committerPaul Janzen <pjanzen@cvs.openbsd.org>2001-02-23 19:14:22 +0000
commitbcb2c8c6088b0832b8ea763643704af3120b8771 (patch)
treecf6e58edb20253ee2cc292bf20d966ebcc519924 /usr.bin/du/du.c
parent9e45c638ba08626a4bc2b6fbae0fb95689848e66 (diff)
Add -h option ("human-readable") as df. Based on suggestions and code from
Matt Bing <matt@anzen.com>.
Diffstat (limited to 'usr.bin/du/du.c')
-rw-r--r--usr.bin/du/du.c99
1 files changed, 82 insertions, 17 deletions
diff --git a/usr.bin/du/du.c b/usr.bin/du/du.c
index 718739235d9..f26e7cf365d 100644
--- a/usr.bin/du/du.c
+++ b/usr.bin/du/du.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: du.c,v 1.6 2000/04/16 04:21:34 ericj Exp $ */
+/* $OpenBSD: du.c,v 1.7 2001/02/23 19:14:21 pjanzen Exp $ */
/* $NetBSD: du.c,v 1.11 1996/10/18 07:20:35 thorpej Exp $ */
/*
@@ -47,7 +47,7 @@ static char copyright[] =
#if 0
static char sccsid[] = "@(#)du.c 8.5 (Berkeley) 5/4/95";
#else
-static char rcsid[] = "$OpenBSD: du.c,v 1.6 2000/04/16 04:21:34 ericj Exp $";
+static char rcsid[] = "$OpenBSD: du.c,v 1.7 2001/02/23 19:14:21 pjanzen Exp $";
#endif
#endif /* not lint */
@@ -58,12 +58,14 @@ static char rcsid[] = "$OpenBSD: du.c,v 1.6 2000/04/16 04:21:34 ericj Exp $";
#include <err.h>
#include <errno.h>
#include <fts.h>
+#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int linkchk __P((FTSENT *));
+void prtout __P((quad_t, char *, int));
void usage __P((void));
int
@@ -73,16 +75,18 @@ main(argc, argv)
{
FTS *fts;
FTSENT *p;
- long blocksize, totalblocks;
+ long blocksize;
+ quad_t totalblocks;
int ftsoptions, listdirs, listfiles;
- int Hflag, Lflag, Pflag, aflag, ch, cflag, kflag, notused, rval, sflag;
+ int Hflag, Lflag, Pflag, aflag, cflag, hflag, kflag, sflag;
+ int ch, notused, rval;
char **save;
save = argv;
- Hflag = Lflag = Pflag = aflag = cflag = kflag = sflag = 0;
+ Hflag = Lflag = Pflag = aflag = cflag = hflag = kflag = sflag = 0;
totalblocks = 0;
ftsoptions = FTS_PHYSICAL;
- while ((ch = getopt(argc, argv, "HLPacksxr")) != -1)
+ while ((ch = getopt(argc, argv, "HLPachksxr")) != -1)
switch (ch) {
case 'H':
Hflag = 1;
@@ -102,6 +106,9 @@ main(argc, argv)
case 'c':
cflag = 1;
break;
+ case 'h':
+ hflag = 1;
+ break;
case 'k':
blocksize = 1024;
kflag = 1;
@@ -157,7 +164,7 @@ main(argc, argv)
argv[1] = NULL;
}
- if (!kflag)
+ if (!kflag || hflag)
(void)getbsize(&notused, &blocksize);
blocksize /= 512;
@@ -179,9 +186,8 @@ main(argc, argv)
* root of a traversal, display the total.
*/
if (listdirs || (!listfiles && !p->fts_level))
- (void)printf("%ld\t%s\n",
- howmany(p->fts_number, blocksize),
- p->fts_path);
+ prtout((quad_t)howmany(p->fts_number, blocksize),
+ p->fts_path, hflag);
break;
case FTS_DC: /* Ignore. */
break;
@@ -199,18 +205,17 @@ main(argc, argv)
* the root of a traversal, display the total.
*/
if (listfiles || !p->fts_level)
- (void)printf("%qd\t%s\n",
- howmany(p->fts_statp->st_blocks, blocksize),
- p->fts_path);
+ prtout(howmany(p->fts_statp->st_blocks, blocksize),
+ p->fts_path, hflag);
p->fts_parent->fts_number += p->fts_statp->st_blocks;
if (cflag)
totalblocks += p->fts_statp->st_blocks;
}
if (errno)
err(1, "fts_read");
- if (cflag)
- (void)printf("%ld\ttotal\n",
- howmany(totalblocks, blocksize));
+ if (cflag) {
+ prtout((quad_t)howmany(totalblocks, blocksize), "total", hflag);
+ }
exit(rval);
}
@@ -245,11 +250,71 @@ linkchk(p)
return (0);
}
+/*
+ * "human-readable" output: use 3 digits max.--put unit suffixes at
+ * the end. Makes output compact and easy-to-read.
+ */
+
+typedef enum { NONE = 0, KILO, MEGA, GIGA, TERA, PETA /* , EXA */ } unit_t;
+
+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
+prtout(size, path, hflag)
+ quad_t size;
+ char *path;
+ int hflag;
+{
+ unit_t unit;
+ double bytes;
+
+ if (!hflag)
+ (void)printf("%qd\t%s\n", size, path);
+ else {
+ bytes = (double)size * 512.0;
+ unit = unit_adjust(&bytes);
+
+ if (bytes == 0)
+ (void)printf(" 0B\t%s\n", path);
+ else if (bytes > 10)
+ (void)printf("%.0f%c\t%s\n", bytes, "BKMGTPE"[unit], path);
+ else
+ (void)printf("%.1f%c\t%s\n", bytes, "BKMGTPE"[unit], path);
+ }
+}
+
void
usage()
{
(void)fprintf(stderr,
- "usage: du [-H | -L | -P] [-a | -s] [-ckrx] [file ...]\n");
+ "usage: du [-H | -L | -P] [-a | -s] [-chkrx] [file ...]\n");
exit(1);
}