Subject: Patch #2 for df(1)
To: None <tech-userlevel@netbsd.org>
From: Tomas Svensson <tsn@gbdev.net>
List: tech-userlevel
Date: 11/19/2001 21:33:56
Here is a new patch for df(1) with -H added, manpage updated and it's no
longer using FP math (even if its not really as simple as Brian suggests
if we want to avoid precision loss and round sizes properly).
The P-flag is just ignored if combined with -h or -H (does the same on
GNU, depends on the order on FreeBSD). Changing this behavior will not
make a lot of sense unless all exclusive flags give an error when used
together.
-Tomas
diff -u df1/df.1 df/df.1
--- df1/df.1 Sun Nov 18 23:08:29 2001
+++ df/df.1 Mon Nov 19 18:22:27 2001
@@ -41,7 +41,7 @@
.Nd display free disk space
.Sh SYNOPSIS
.Nm
-.Op Fl aiklmnP
+.Op Fl aghHiklmnP
.Op Fl t Ar type
.Op Ar file | Ar file_system ...
.Sh DESCRIPTION
@@ -51,7 +51,7 @@
or on the file system of which
.Ar file
is a part.
-Values are displayed in 512-byte per block block counts.
+Values are displayed in 512-byte per block counts.
If neither a file or a
.Ar file_system
operand is specified,
@@ -74,22 +74,30 @@
Show all filesystems. By default only filesystems mounted with the
.Dv MNT_IGNORE
flag clear are shown.
+.It Fl g
+Use 1073741824-byte (gigabyte) block counts rather than the default. This
+overrides the BLOCKSIZE specification from the environment.
+.It Fl h
+Display sizes in a more "human-readable" and compact form. Use unit suffixes:
+Byte, Kilobyte, Megabyte, Gigabyte, Terabyte, Petabyte and Exabyte in order to
+reduce the number of digits to four or fewer using base 2 for sizes.
+.It Fl H
+Same as
+.Fl h
+but using base 10 for sizes.
.It Fl i
Include statistics on the number of free inodes.
.It Fl k
-By default, all sizes are reported in 512-byte block counts.
-The
-.Fl k
-option causes the numbers to be reported in kilobyte (1024 bytes) counts.
+Use 1024-byte (kilobyte) block counts rather than the default. This overrides
+the BLOCKSIZE specification from the environment.
.It Fl l
Display statistics only about mounted file systems with the
.Dv MNT_LOCAL
flag set. If a non-local file system is given as an argument, a
warning is issued and no information is given on that file system.
.It Fl m
-The
-.Fl m
-option causes the numbers to be reported in megabyte (1024*1024 bytes) counts.
+Use 1048576-byte (megabyte) block counts rather than the default. This
+overrides the BLOCKSIZE specification from the environment.
.It Fl n
Print out the previously obtained statistics from the file systems.
This option should be used if it is possible that one or more
@@ -146,6 +154,9 @@
If the environment variable
.Ev BLOCKSIZE
is set, and the
+.Fl g
+.Fl h
+.Fl H
.Fl k
and
.Fl m
diff -u df1/df.c df/df.c
--- df1/df.c Sun Nov 18 23:08:29 2001
+++ df/df.c Mon Nov 19 18:30:22 2001
@@ -72,14 +72,15 @@
int main(int, char *[]);
int bread(off_t, void *, int);
char *getmntpt(char *);
-void prtstat(struct statfs *, int);
+void prthuman(int64_t, int);
+void prtstat(struct statfs *, int, int);
int ufs_df(char *, struct statfs *);
int selected(const char *);
void maketypelist(char *);
long regetmntinfo(struct statfs **, long);
void usage(void);
-int aflag, iflag, kflag, lflag, mflag, nflag, Pflag;
+int aflag, gflag, hflag, iflag, kflag, lflag, mflag, nflag, Pflag;
char **typelist = NULL;
struct ufs_args mdev;
@@ -89,14 +90,25 @@
struct stat stbuf;
struct statfs *mntbuf;
long mntsize;
- int ch, i, maxwidth, width;
+ int base, ch, i, maxwidth, width;
char *mntpt;
- while ((ch = getopt(argc, argv, "aiklmnPt:")) != -1)
+ while ((ch = getopt(argc, argv, "aghHiklmnPt:")) != -1)
switch (ch) {
case 'a':
aflag = 1;
break;
+ case 'g':
+ gflag = 1;
+ break;
+ case 'h':
+ hflag = 1;
+ base = 1024;
+ break;
+ case 'H':
+ hflag = 1;
+ base = 1000;
+ break;
case 'i':
iflag = 1;
break;
@@ -203,7 +215,7 @@
maxwidth = width;
}
for (i = 0; i < mntsize; i++)
- prtstat(&mntbuf[i], maxwidth);
+ prtstat(&mntbuf[i], maxwidth, base);
exit(0);
/* NOTREACHED */
}
@@ -326,10 +338,49 @@
(num) / ((bs) / (fsbs)) : (num) * ((fsbs) / (bs)))
/*
+ * Print statistics in a more "human-readable" and compact form.
+ */
+void
+prthuman(int64_t bytes, int base)
+{
+ int i, neg, size1, size2, unit;
+
+ if (bytes == 0)
+ (void)printf(" 0B");
+ else {
+ i = 0;
+ if (bytes < 0) {
+ bytes *= -100;
+ neg = -1;
+ } else {
+ bytes *= 100;
+ neg = 1;
+ }
+ for(unit = -1; unit == -1; i++)
+ if ((bytes / 100) < base || i == 6)
+ unit = i;
+ else
+ bytes /= base;
+ if (bytes > 1000)
+ (void)printf(" %5lli%c",(neg * ((bytes + 50) / 100)),
+ "BKMGTPE"[unit]);
+ else {
+ size1 = bytes / 100;
+ if ((size2 = (((bytes % 100) + 5) / 10)) == 10) {
+ size1++;
+ size2 = 0;
+ }
+ (void)printf(" %3i.%1i%c", neg * size1, neg * size2,
+ "BKMGTPE"[unit]);
+ }
+ }
+}
+
+/*
* Print out status about a filesystem.
*/
void
-prtstat(struct statfs *sfsp, int maxwidth)
+prtstat(struct statfs *sfsp, int maxwidth, int base)
{
static long blocksize;
static int headerlen, timesthrough;
@@ -340,19 +391,30 @@
if (maxwidth < 11)
maxwidth = 11;
if (++timesthrough == 1) {
- if (kflag) {
- blocksize = 1024;
- header = Pflag ? "1024-blocks" : "1K-blocks";
- headerlen = strlen(header);
- } else if (mflag) {
- blocksize = 1024 * 1024;
- header = Pflag ? "1048576-blocks" : "1M-blocks";
- headerlen = strlen(header);
- } else
- header = getbsize(&headerlen, &blocksize);
- (void)printf("%-*.*s %s Used %9s Capacity",
- maxwidth, maxwidth, "Filesystem", header,
- Pflag ? "Available" : "Avail");
+ if (hflag)
+ (void)printf("%-*.*s Size Used Avail Capacity",
+ maxwidth, maxwidth, "Filesystem");
+ else {
+ if (kflag) {
+ blocksize = 1024;
+ header = Pflag ? "1024-blocks" : "1K-blocks";
+ headerlen = strlen(header);
+ } else if (mflag) {
+ blocksize = 1024 * 1024;
+ header = Pflag ? "1048576-blocks" :
+ "1M-blocks";
+ headerlen = strlen(header);
+ } else if (gflag) {
+ blocksize = 1024 * 1024 * 1024;
+ header = Pflag ? "1073741824-blocks" :
+ "1G-blocks";
+ headerlen = strlen(header);
+ } else
+ header = getbsize(&headerlen, &blocksize);
+ (void)printf("%-*.*s %s Used %9s Capacity",
+ maxwidth, maxwidth, "Filesystem", header,
+ Pflag ? "Available" : "Avail");
+ }
if (iflag)
(void)printf(" iused ifree %%iused");
(void)printf(" Mounted on\n");
@@ -360,10 +422,15 @@
(void)printf("%-*.*s", maxwidth, maxwidth, sfsp->f_mntfromname);
used = sfsp->f_blocks - sfsp->f_bfree;
availblks = sfsp->f_bavail + used;
- (void)printf(" %*ld %8ld %9ld", 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((int64_t)sfsp->f_blocks * (int64_t)sfsp->f_bsize, base);
+ prthuman((int64_t)used * (int64_t)sfsp->f_bsize, base);
+ prthuman((int64_t)sfsp->f_bavail * (int64_t)sfsp->f_bsize, base);
+ } else
+ (void)printf(" %*ld %8ld %9ld", 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("%7s",
availblks == 0 ? full : strpct((u_long)used, (u_long)availblks, 0));
if (iflag) {
@@ -460,7 +527,7 @@
{
(void)fprintf(stderr,
- "Usage: %s [-aiklmnP] [-t type] [file | file_system ...]\n",
+ "Usage: %s [-aghHiklmnP] [-t type] [file | file_system ...]\n",
getprogname());
exit(1);
/* NOTREACHED */