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>
This commit is contained in:
parent
61075c3a9d
commit
a67c7a1db7
@ -8,6 +8,8 @@ BINMODE=2555
|
||||
|
||||
MOUNT= ${.CURDIR}/../../sbin/mount
|
||||
CFLAGS+= -I${MOUNT}
|
||||
LDADD+= ${LIBM}
|
||||
DPADD+= ${LIBM}
|
||||
.PATH: ${MOUNT}
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
26
bin/df/df.1
26
bin/df/df.1
@ -40,7 +40,8 @@
|
||||
.Nd display free disk space
|
||||
.Sh SYNOPSIS
|
||||
.Nm df
|
||||
.Op Fl aikn
|
||||
.Op Fl b | h | H | k | m | P
|
||||
.Op Fl ain
|
||||
.Op Fl t Ar type
|
||||
.Op Ar file | Ar filesystem ...
|
||||
.Sh DESCRIPTION
|
||||
@ -62,6 +63,19 @@ The following options are available:
|
||||
.It Fl a
|
||||
Show all mount points, including those that were mounted with the MNT_IGNORE
|
||||
flag.
|
||||
.It Fl b
|
||||
Use 512-byte blocks rather than the default. Note that
|
||||
this overrides the
|
||||
.Ev BLOCKSIZE
|
||||
specification from the environment.
|
||||
.It Fl H
|
||||
"Human-readable" output. Use unit suffixes: Byte, Kilobyte, Megabyte,
|
||||
Gigabyte, Terabyte and Petabyte in order to reduce the number of
|
||||
digits to three or less using base 10 for sizes.
|
||||
.It Fl h
|
||||
"Human-readable" output. Use unit suffixes: Byte, Kilobyte, Megabyte,
|
||||
Gigabyte, Terabyte and Petabyte in order to reduce the number of
|
||||
digits to three or less using base 2 for sizes.
|
||||
.It Fl i
|
||||
Include statistics on the number of free inodes.
|
||||
.It Fl k
|
||||
@ -69,6 +83,11 @@ Use 1024-byte (1-Kbyte) blocks rather than the default. Note that
|
||||
this overrides the
|
||||
.Ev BLOCKSIZE
|
||||
specification from the environment.
|
||||
.It Fl m
|
||||
Use 1048576-byte (1-Mbyte) blocks rather than the default. Note that
|
||||
this overrides the
|
||||
.Ev BLOCKSIZE
|
||||
specification from the environment.
|
||||
.It Fl n
|
||||
Print out the previously obtained statistics from the filesystems.
|
||||
This option should be used if it is possible that one or more
|
||||
@ -78,6 +97,11 @@ When this option is specified,
|
||||
.Nm
|
||||
will not request new statistics from the filesystems, but will respond
|
||||
with the possibly stale statistics that were previously obtained.
|
||||
.It Fl P
|
||||
Use POSIX compliant output of 512-byte blocks rather than the default.
|
||||
Note that this overrides the
|
||||
.Ev BLOCKSIZE
|
||||
specification from the environment.
|
||||
.It Fl t
|
||||
Only print out statistics for filesystems of the specified types.
|
||||
More than one type may be specified in a comma separated list.
|
||||
|
142
bin/df/df.c
142
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;
|
||||
@ -248,6 +301,61 @@ regetmntinfo(mntbufp, mntsize, vfslist)
|
||||
return (j);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user