Subject: bin/18402: fixed du(1), added -h option to display human-readable format
To: None <gnats-bugs@gnats.netbsd.org>
From: Benedikt Meurer <bmeurer@fwdn.de>
List: netbsd-bugs
Date: 09/24/2002 20:02:16
>Number: 18402
>Category: bin
>Synopsis: added -h option, as found on other plattforms
>Confidential: no
>Severity: non-critical
>Priority: high
>Responsible: bin-bug-people
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Tue Sep 24 11:03:00 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator: Benedikt Meurer
>Release: NetBSD 1.6
>Organization:
University Siegen
>Environment:
System: NetBSD endor.kosmos.all 1.6 NetBSD 1.6 (ENDOR) #1: Tue Sep 24 16:20:31 CEST 2002 benny@endor.kosmos.all:/usr/src/sys/arch/i386/compile/ENDOR i386
Architecture: i386
Machine: i386
>Description:
I've added the -h option to du, allowing it to display the numbers in
a "human-readable" format as found on other plattforms. I also make lint
happier about du.c and fixed the exit failure, since exit should return
"rval" not just 0, in case somethings went wrong. Also fixes a potential
bug with totalblocks too small (type long), and added l10n support.
>How-To-Repeat:
>Fix:
Patch follows.
Index: du.1
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/du/du.1,v
retrieving revision 1.12
diff -u -r1.12 du.1
--- du.1 2001/12/01 19:03:31 1.12
+++ du.1 2002/09/24 17:23:45
@@ -43,7 +43,7 @@
.Nm
.Op Fl H | Fl L | Fl P
.Op Fl a | Fl s
-.Op Fl ckmrx
+.Op Fl chkmrx
.Op Ar file ...
.Sh DESCRIPTION
The
@@ -80,6 +80,12 @@
.Fl m
flag is specified, the number displayed is the number of megabyte
(1024*1024 bytes) blocks.
+.It Fl h
+If the
+.Fl h
+flag is specified, the numbers will be displayed in "human-readable"
+format. Use unit suffixes: B (Byte), K (Kilobyte), M (Megabyte),
+G (Gigabyte), T (Terabyte) and P (Petabyte).
.It Fl c
Display the grand total after all the arguments have been processed.
.It Fl r
Index: du.c
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/du/du.c,v
retrieving revision 1.17
diff -u -r1.17 du.c
--- du.c 2001/01/04 23:05:54 1.17
+++ du.c 2002/09/24 17:23:46
@@ -57,6 +57,7 @@
#include <err.h>
#include <errno.h>
#include <fts.h>
+#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -64,8 +65,13 @@
int linkchk __P((FTSENT *));
int main __P((int, char **));
+void prstat __P((const char *, int64_t));
void usage __P((void));
+/* used by prstat */
+long blocksize;
+int hflag;
+
int
main(argc, argv)
int argc;
@@ -73,27 +79,26 @@
{
FTS *fts;
FTSENT *p;
- long blocksize, totalblocks;
+ int64_t totalblocks;
int ftsoptions, listdirs, listfiles;
- int Hflag, Lflag, Pflag, aflag, ch, cflag, kmflag, notused, rval, sflag;
+ int Hflag, Lflag, aflag, ch, cflag, kmflag, notused, rval, sflag;
char **save;
save = argv;
- Hflag = Lflag = Pflag = aflag = cflag = kmflag = sflag = 0;
+ Hflag = Lflag = aflag = cflag = kmflag = sflag = 0;
totalblocks = 0;
ftsoptions = FTS_PHYSICAL;
- while ((ch = getopt(argc, argv, "HLPackmrsx")) != -1)
+ while ((ch = getopt(argc, argv, "HLPachkmrsx")) != -1)
switch (ch) {
case 'H':
Hflag = 1;
- Lflag = Pflag = 0;
+ Lflag = 0;
break;
case 'L':
Lflag = 1;
- Hflag = Pflag = 0;
+ Hflag = 0;
break;
case 'P':
- Pflag = 1;
Hflag = Lflag = 0;
break;
case 'a':
@@ -102,6 +107,9 @@
case 'c':
cflag = 1;
break;
+ case 'h':
+ hflag = 1;
+ break;
case 'k':
blocksize = 1024;
kmflag = 1;
@@ -183,9 +191,7 @@
* 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);
+ prstat(p->fts_path, (int64_t)p->fts_number);
break;
case FTS_DC: /* Ignore. */
break;
@@ -203,9 +209,7 @@
* the root of a traversal, display the total.
*/
if (listfiles || !p->fts_level)
- (void)printf("%lld\t%s\n", (long long)
- howmany(p->fts_statp->st_blocks, blocksize),
- p->fts_path);
+ prstat(p->fts_path, p->fts_statp->st_blocks);
p->fts_parent->fts_number += p->fts_statp->st_blocks;
if (cflag)
totalblocks += p->fts_statp->st_blocks;
@@ -213,9 +217,28 @@
if (errno)
err(1, "fts_read");
if (cflag)
- (void)printf("%ld\ttotal\n",
- howmany(totalblocks, blocksize));
- exit(0);
+ prstat("total", totalblocks);
+ exit(rval);
+}
+
+void
+prstat (fname, blocks)
+ const char *fname;
+ int64_t blocks;
+{
+ static char sznam[] = {'B', 'K', 'M', 'G', 'T', 'P'};
+
+ if (hflag) {
+ double sz = blocks * 512;
+ int n = 0;
+
+ for ( ; sz >= 1024; n++, sz /= 1024)
+ ;
+ (void)printf("%.1f%c\t%s\n", sz, sznam[n], fname);
+ }
+ else
+ (void)printf("%lld\t%s\n", howmany(blocks, (int64_t)blocksize),
+ fname);
}
typedef struct _ID {
@@ -254,6 +277,6 @@
{
(void)fprintf(stderr,
- "usage: du [-H | -L | -P] [-a | -s] [-ckmrx] [file ...]\n");
+ "usage: du [-H | -L | -P] [-a | -s] [-chkmrx] [file ...]\n");
exit(1);
}
>Release-Note:
>Audit-Trail:
>Unformatted: